java - 想象一个真实的并发场景,应该使用StringBuffer而不是StringBuilder?

标签 java concurrency thread-safety stringbuilder stringbuffer

我知道 StringBuffer 和 StringBuilder 的区别。 read here !

一般来说,正如 javadoc 所说,

Where possible, it is recommended that this class be used in preference to StringBuffer as it will be faster under most implementations.

但是,StringBuilder 的 javadoc 也说:

Instances of StringBuilder are not safe for use by multiple threads. If such synchronization is required then it is recommended that {@link java.lang.StringBuffer} be used

所以,我想知道,是否真的存在首选 StringBuffer 的情况?由于可变字符串主要在单线程中使用,谁能给我一个首选 StringBuffer 的并发真实场景?

最佳答案

StringBuffer 是线程安全的原因是,在设计第一个版本的 java api 的那一天,人们对并发的处理方式与现在不同。普遍的观点是对象应该是线程安全的——因为 Java 支持线程,人们可以在多线程中使用任何 JDK 类。后来,当 Java 开始针对执行时间进行优化时,那些不必要的同步块(synchronized block)的成本开始成为一个问题,因此较新的 API 被设计为不同步。再后来,JVM 开始优化锁,使无竞争的锁基本上免费,使整个决定成为一个有争议的问题。

StringBuffer 仍然是线程安全的,因为旧代码可能依赖于它是线程安全的。这远非典型用途,但可以想象。

例如,假设您正在编写一个将日志条目转发到中央服务器的日志文件附加程序。因为我们不想在等待网络 I/O 时阻塞调用者,所以我们在专用线程中执行此操作。其他线程会将它们的日志条目累积在 StringBuffer 中:

class RemoteLogger implements Runnable, Appender {
    final StringBuffer buffer = new StringBuffer();

    void append(String s) {
        buffer.append(s);
    }

    public void run() {
        for (;;) {
            Thread.sleep(100);

            String message = buffer.toString();
            sendToServer(message);
            buffer.delete(0, message.length());
        }
    }
}

关于java - 想象一个真实的并发场景,应该使用StringBuffer而不是StringBuilder?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16653119/

相关文章:

java - java.rmi.Naming 和 java.rmi.registry.LocateRegistry 有什么区别

java - Hangman While 循环解决方案

concurrency - Elixir/Erlang 和 Cowboy - 如何使用主管

c# - 状态机问题

java - Java中什么情况下需要同步数组?

c - 在线程内创建变量和传递指针的问题

java - 单元测试由@Around 建议建议的方法

java - Java并发,Akka和RxJava之间的区别?

C++ 并发 GET 请求

java - 收集一类 JUnit 中的所有测试