StringBuffer在多线程下无性能优势,仅保障线程安全;其synchronized方法导致锁开销、线程阻塞和吞吐下降,性能实测低于StringBuilder,但能确保共享修改时结果正确。

StringBuffer在多线程环境下没有性能优势,只有线程安全优势;它的性能实际是低于StringBuilder的,但换来了并发操作的可靠性。
为什么说“性能优势”是个常见误解
很多人误以为StringBuffer“更适合多线程所以更快”,其实恰恰相反:它的所有公共方法(如append、insert、delete)都加了synchronized锁,意味着同一时刻只能一个线程执行。这种串行化机制会带来明显开销:
- 锁获取与释放本身消耗CPU周期
- 线程争抢导致阻塞和上下文切换
- 高并发时大量线程排队等待,吞吐量下降
它真正不可替代的价值是线程安全
当多个线程共享并修改同一个字符串对象时,StringBuffer能保证结果始终正确——不会丢字符、不会乱序、不会抛异常。例如:
- 日志聚合器中多个工作线程向同一缓冲区写入日志行
- 配置构建器中多个初始化线程拼接不同模块的参数
- Web应用中Filter链共用一个响应内容收集器(虽不推荐,但可行)
这些场景下,用StringBuilder会出现长度不一致、输出缺失或ArrayIndexOutOfBoundsException等非预期行为,而StringBuffer始终返回确定结果。
立即学习“Java免费学习笔记(深入)”;
性能对比的关键事实
实测数据(JDK 17+,4核CPU)显示:
- 单线程循环拼接10万次:StringBuilder比StringBuffer快约25%–30%
- 4线程并发拼接各10万次:
• StringBuilder最终长度常小于40万(丢失更新)
• StringBuffer稳定输出40万,但耗时比单线程StringBuilder高约2.8倍 - 锁竞争越激烈(线程数↑、操作粒度↓),StringBuffer相对性能越差
更优的实战建议
与其依赖StringBuffer扛高并发,不如从设计上规避共享:
- 每个线程使用独立的StringBuilder,最后再合并
- 用ThreadLocal
隔离实例,避免锁又复用对象 - 对极少量共享拼接需求,改用ConcurrentHashMap或原子引用配合CAS
- 若必须用StringBuffer,预先设置合理初始容量(如new StringBuffer(4096)),减少扩容锁竞争



















