stringbuffer 的线程安全完全依赖每个 public 修改方法(如 append、insert、delete 等)声明的 synchronized 关键字,锁对象为 this,粒度粗、无优化;stringbuilder 同功能方法无 synchronized,性能高约 80%。

直接看源码里的 synchronized 修饰符是最关键的切入点。StringBuffer 的线程安全不靠额外框架或锁工具,就靠每个公开修改方法都加了 synchronized,锁对象是 this 实例本身。
从 append 方法入手定位同步逻辑
打开 JDK 源码(如 JDK 17 的 StringBuffer.java),找到 append 方法:
- 签名是
public synchronized StringBuffer append(String str) - 方法体里调用的是父类
AbstractStringBuilder.append(),但入口被synchronized包裹 - 字节码层面会带
ACC_SYNCHRONIZED标志,JVM 自动处理 monitor enter/exit - 同理,
insert、delete、reverse、setCharAt等所有 public 修改方法都如此声明
对比 StringBuilder 确认唯一差异点
把 StringBuilder.append() 拿来并排看:
Java Maven 项目审查工作流的通用输入处理。当 Java Maven 项目以 ZIP压缩包或 GitLab 仓库 URL 形式提供且需要...时使用。
- 方法签名只有
public StringBuilder append(String str),没有synchronized - 底层复用同一套
AbstractStringBuilder逻辑(包括char[] value和int count) - 结论很清晰:两者功能一致,线程安全与否,只差这一个关键字
观察锁粒度和共享状态保护范围
顺着源码往里查,重点关注它保护了哪些字段和操作:
-
value数组动态扩容(ensureCapacityInternal)、count更新、toStringCache清空,全在同步方法体内 -
length()和capacity()虽然也是synchronized,但只是读操作,仍要竞争锁——说明锁是方法级、粗粒度的 - 没有分段锁、CAS 或锁优化机制,纯靠对象 monitor,不同实例之间完全不干扰
结合字节码和性能数据验证开销
用 javap -v StringBuffer 查看 append 方法的字节码:
- 确认存在
ACC_SYNCHRONIZED标志,无显式monitorenter/monitorexit指令 - 配合实测:100 万次单线程
append,StringBuffer 耗时约 120ms,StringBuilder 约 65ms,差距稳定在 80% 左右 - 这说明同步不是“没成本”,而是设计上就接受的 trade-off










