String构建器如何管理多线程访问单个对象和可变性?

时间:2016-02-07 14:59:04

标签: java string stringbuilder stringbuffer mutability

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

2 个答案:

答案 0 :(得分:1)

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

这种能力的代价是,当2个线程同时访问StringBuffer实例时,第二个线程被阻塞,直到第一个线程处理缓冲区为止。这意味着您的多线程系统在这段时间内变为面对线。如果发生这种情况,系统的性能通常会低于没有锁的情况。

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

答案 1 :(得分:1)

如果你只调用一个方法,StringBuffer只是线程安全的。 SimpleDateFormat使用StringBuffer但不是线程安全的(它是由JVM开发人员编写的)。以线程安全的方式使用StringBuffer并不容易,并且正确。

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

  

如何使用显式同步或锁定 -

您在操作周围放置synchronized

e.g。写一个新行

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<>();

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