0

String 的劣势如何成为 String-builder 的优势。我的意思是我已经知道字符串是不可变的,因为如果假设有五个 String 对象并且如果一个对象发生变化,那么它将反映所有内容并可能导致运行时错误,之后 String-Buffer 是可变的,但至少它是一次同步一个线程。事情进展顺利,最后现在 String-builder 可变,可以访问多个线程。使用起来这么复杂?程序员如何管理它。

4

2 回答 2

1

StringBuffer是同步的,这意味着它的所有方法都是syncrhonized,所以它可以在多线程环境中安全地使用,即多个线程可以 StringBuffer安全地更改和检索实例的内容。

这种能力的代价是当两个线程同时访问StringBuffer实例时,第二个线程被阻塞,直到第一个线程处理缓冲区。这意味着您的多线程系统在这段时间内变成了单线程。如果这种情况经常发生,您的系统性能可能会比没有锁的情况低得多。

StringBuilder不同步。这意味着如果 2 个线程同时更改其状态,则结果是不可预测的。因此,您应该自己管理访问策略,方法是同步提供对实例的访问权限的方法,StringBuilder或者避免多线程访问,例如使用真正不可变的对象(如字符串)或实际上不可变的对象(如每个线程的构建器)。

于 2016-02-07T15:13:05.887 回答
1

StringBuffer 仅在您调用一种且仅一种方法时才是线程安全的。 SimpleDateFormat 使用 StringBuffer 但不是线程安全的(它是由 JVM 开发人员编写的)。以线程安全的方式使用 StringBuffer 并做到正确并不容易。

您最好使用十年前取代 StringBuffer 并使用显式synchronizedLock. 对于您的用例,这可能实际上是线程安全的。

如何使用显式同步或锁 -</p>

你在你的操作周围放置一个synchronized

例如写一个新行

synchronized(sb) {
   sb.append("data: ");
   sb.append(data);
   sb.append("\n");
}

或抓取内容

String s;
synchronized(sb) {
    s = sb.toString(); // no simple way to control how many messages you get
    sb.setLength(0);
}

程序员如何管理它。

您很可能想要一种不同的方法。这是因为没有办法轮询 StringBuilder/StringBuffer 并询问它;你完成了吗?如果我读到你,我可以用简单的方式清除它,以便可以重用缓冲区。如果没有可用的数据,没有简单的方法可以阻止。作家也没有并发性。

如果您想在线程之间共享文本流,我建议使用

BlockingQueue<String> textStream = new ConcurrentLinkedQueue<>();

这将是线程安全的,支持并发写入和读取,并且您可以阻止等待一些数据并知道它正是一条消息。

于 2016-02-07T15:22:06.890 回答