StringBuilder无同步机制,StringBuffer所有可变操作方法均加synchronized修饰,确保线程安全但性能较低;二者仅方法声明处同步修饰符不同,导致运行时锁行为与内存可见性差异。

区分 StringBuilder 与 StringBuffer 的同步机制,关键看“有没有 synchronized”以及“谁来负责线程安全”。
同步机制体现在每个公共方法上
StringBuffer 的所有可变操作方法(如 append()、insert()、delete()、reverse())都明确加了 synchronized 修饰符。这意味着:
- 每次调用这些方法,都会尝试获取当前对象的监视器锁(monitor lock)
- 如果多个线程同时调用同一个 StringBuffer 实例的方法,它们会被强制排队执行
- JVM 会插入内存屏障,确保修改对其他线程可见
StringBuilder 完全不加同步修饰
StringBuilder 对应的同名方法(如 append())没有 synchronized,也没有任何内部锁逻辑:
- 方法体直接执行底层字符数组操作,无锁竞争开销
- 不保证多线程并发访问时的数据一致性
- 编译器更易对其做内联优化,尤其在循环中高频调用时
同步不是靠“类名”或“文档”判断,而是看源码行为
两者继承自同一个父类 AbstractStringBuilder,共享大部分实现逻辑。真正拉开同步差异的是这一行写法:
-
public synchronized StringBuffer append(String str)—— StringBuffer -
public StringBuilder append(String str)—— StringBuilder
仅此一处修饰符不同,就决定了运行时是否进入同步块、是否触发锁膨胀、是否产生内存屏障等底层行为。
同步开销不是“有或无”的简单标签
它直接影响执行路径:
- 单线程下,StringBuffer 多出锁获取/释放、内存屏障、可能的锁升级过程,实测慢约 40%
- 多线程共享同一实例时,StringBuilder 的“快”会变成“错”,结果不可靠;StringBuffer 的“慢”换来了 100% 正确性

















