stringbuffer因全方法同步导致多线程性能严重下降,所有public方法(含只读操作)均加synchronized锁this,引发锁竞争、串行化读写及扩容双重同步开销,4线程下耗时超单线程stringbuilder的2.8倍。

StringBuffer 在多线程环境下确实能保证数据安全,但它的同步机制会显著拖慢性能——不是“有点慢”,而是锁竞争直接吃掉吞吐量。
所有方法都锁整个对象
append、insert、delete、toString 等 public 方法全部加了 synchronized,锁的是 this 实例。这意味着:
- 哪怕两个线程往字符串两端写不同内容,也必须排队等待同一把锁
- 高并发时大量线程阻塞或自旋,CPU 时间花在锁调度而非拼接上
- 链式调用如
sb.append("a").append("b").append("c")会进出同步块三次,开销叠加
扩容时触发双重同步
当内部 char[] 不够用,StringBuffer 按 新容量 = 旧容量 × 2 + 2 扩容。这个过程分两步同步:
- 先同步检查容量是否足够
- 再同步执行数组复制和替换
- 多个线程几乎同时扩容,可能重复拷贝、争抢锁、放大延迟
读操作也被同步拖累
很多人忽略:length()、charAt() 这类只读方法同样被 synchronized 修饰。结果是:
- 即使没有写操作,多个线程读取也会串行化
- 无法利用 CPU 多核并行读取,白白损失并发能力
- JIT 虽能优化无竞争同步,但一旦有真实竞争,monitor enter/exit 开销就实打实出现
对比数据很说明问题
10 万次拼接基准测试(JDK 21,4 核):
- StringBuilder(单线程):约 12ms
- StringBuffer(单线程):约 28ms
- 4 线程共用 StringBuffer:耗时飙升至单线程 StringBuilder 的 2.8 倍以上,且 P99 延迟抖动明显
这不是常数级变慢,而是随着线程数增加呈非线性恶化——锁成了瓶颈本身。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











