stringbuilder比stringbuffer快2–3.5倍,因其所有方法均无synchronized,避免了锁检查、内存屏障和释放等同步开销;二者底层实现完全一致,性能差异仅源于同步机制。

直接看同步开销——这是唯一决定性因素。StringBuilder 比 StringBuffer 快,不是因为算法更优、扩容更快或内存更省,而是因为它所有方法都不加 synchronized,彻底跳过了锁的获取、内存屏障插入和释放流程。
同步机制带来的是实打实的运行时成本
StringBuffer 的 append()、insert()、delete() 等公开修改方法全部被 synchronized 修饰。即使单线程执行,JVM 仍必须:
- 在每次调用入口检查锁状态(偏向锁撤销、轻量级锁膨胀等路径仍需走)
- 插入读写内存屏障,确保字段修改对其他线程可见(哪怕没有其他线程)
- 在方法退出时完成锁释放逻辑,包括栈帧清理和可能的锁清除操作
这些动作不参与业务逻辑,但消耗 CPU 周期、影响指令流水线,并随调用次数线性累加。
底层实现完全一致,排除干扰项
两者都继承自 AbstractStringBuilder,共享同一套核心行为:
- 内部存储:JDK 9+ 使用可变
byte[],JDK 8 使用char[] - 初始容量:默认都是 16
- 扩容公式:均为
newCapacity = oldLength × 2 + 2,不足时直接扩到所需最小值 - 数组复制:扩容时均调用
System.arraycopy
这意味着任何性能差异都无法归因于内存分配、拷贝或结构设计,只能锁定在同步控制本身。
用可控基准测试量化差距
推荐在目标 JDK(如 JDK 22.0.2)下运行简易 JMH 或手写循环测试:
- 固定操作:10 万次
append("x"),避免 GC 干扰(预热、禁用 System.gc) - 对比对象:分别使用
new StringBuilder()和new StringBuffer() - 典型结果(JDK 22):StringBuilder 约 7–10ms,StringBuffer 约 24–36ms,快约 2–3.5 倍
若操作链更长(如 append().insert().reverse()),差距会进一步拉大,因为每次方法调用都重复承担同步开销。
真实项目中更值得投入的优化点
单纯替换 StringBuffer 为 StringBuilder 虽然有效,但收益常低于以下做法:
- 预估最终长度,显式指定构造容量(如
new StringBuilder(2048)),减少扩容复制 - 复用局部变量,避免在循环内反复创建新实例
- 确认是否真需要可变拼接——静态字符串连接、编译期优化(如常量折叠)通常更快
只要变量是方法内创建、仅本线程使用,StringBuilder 就是合理默认选择,无需额外权衡。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











