stringbuilder单线程性能优于stringbuffer;两者底层实现相同,区别仅在stringbuffer方法加synchronized保证线程安全,而stringbuilder无同步开销;局部变量场景选stringbuilder,多线程共享修改才考虑stringbuffer,且推荐预设容量优化性能。

单线程下拼接字符串,StringBuilder 性能优于 StringBuffer;多线程共享同一缓冲区时,才需要选 StringBuffer 保证线程安全。
底层实现几乎一样
两者都继承自 AbstractStringBuilder,内部用可变 char[](JDK9+ 改为 byte[])存储字符,扩容逻辑相同(新容量 = 旧容量 × 2 + 2),append、insert 等操作行为一致。区别仅在于同步机制。
- StringBuffer 的关键方法(如 append、toString、delete)都加了
synchronized关键字 - StringBuilder 所有方法均无同步修饰,完全依赖调用方保障线程安全
性能差距主要来自同步开销
在纯单线程场景中,synchronized 会带来锁获取、释放及内存可见性保障的额外成本:
- 基准测试显示:10 万次拼接,StringBuilder 比 StringBuffer 快约 10%–15%
- 高竞争环境下(如多个线程反复争抢同一 StringBuffer 实例),性能差距可能进一步拉大
- 若实际并无并发修改,用 StringBuffer 就是白耗资源
线程安全不是“默认选项”,而是明确需求
是否需要 StringBuffer,取决于变量作用域和访问方式:
- 局部变量(方法内创建、只在本线程使用)→ 选 StringBuilder
- 作为类成员被多个线程直接共用且频繁修改 → 才考虑 StringBuffer
- 更推荐做法:避免跨线程共享可变缓冲区,改用不可变结果(如拼完转 String)或线程本地变量(ThreadLocal
)
别忽略容量预设这个小优化
无论选哪个,如果能预估最终字符串长度,初始化时指定容量可减少数组复制次数:
-
new StringBuilder(1024)比new StringBuilder()(默认 16)更适合拼接长文本 - StringBuffer 同理,
new StringBuffer(1024)同样有效 - 过度预估(如设为 100 万)浪费内存,严重低估则频繁扩容,建议略高于预期值
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











