String如何成为String-builder的优势。我的意思是我已经知道字符串是不可变的,因为如果假设有五个String对象,并且如果一个Object中有变化那么它将全部反映并且可能导致运行时错误,之后String-Buffer是可变的但至少它是一次同步一个线程。事情进展顺利,最后现在String-builder可变,有多个线程可以访问。它使用起来如此复杂?程序员如何管理它。
答案 0 :(得分:1)
StringBuffer
已同步,这意味着它的所有方法都是syncrhonized
,因此可以安全地在多线程环境中使用,即多个线程可以安全地更改和检索StringBuffer
实例的内容。
这种能力的代价是,当2个线程同时访问StringBuffer
实例时,第二个线程被阻塞,直到第一个线程处理缓冲区为止。这意味着您的多线程系统在这段时间内变为面对线。如果发生这种情况,系统的性能通常会低于没有锁的情况。
StringBuilder
未同步。这意味着如果2个线程同时改变其状态,则结果是不可预测的。因此,您应该通过同步提供访问StringBuilder
的instanceo的方法或避免多线程访问来自己管理访问策略,例如使用真正不可变的对象(如String)或实际上不可变的对象(例如每个线程的构建器)。
答案 1 :(得分:1)
如果你只调用一个方法,StringBuffer只是线程安全的。 SimpleDateFormat使用StringBuffer但不是线程安全的(它是由JVM开发人员编写的)。以线程安全的方式使用StringBuffer并不容易,并且正确。
最好使用十年前替换StringBuffer的StringBuilder并使用显式synchronized
或Lock
。对于您的用例,这可能实际上是线程安全的。
如何使用显式同步或锁定 -
您在操作周围放置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<>();
这将是线程安全的,支持并发写入和读取,并且您可以阻止等待某些数据,并且知道它只是一条消息。