StringBuffer线程安全靠每个public方法加synchronized锁住this实例,如append方法;底层复用AbstractStringBuilder的可变char[]和count字段;与StringBuilder唯一区别是synchronized关键字,导致多线程下锁竞争性能下降。

StringBuffer 的线程安全不是靠魔法,而是靠每个公开方法都加了 synchronized ——锁住当前实例(this),确保同一时间只有一个线程能执行它的 append、insert、delete 等操作。
同步机制落在每个方法上
翻开 JDK 源码(以 append 为例):
@Override
public synchronized StringBuffer append(String str) {
toStringCache = null;
super.append(str);
return this;
}
关键点很直接:
立即学习“Java免费学习笔记(深入)”;
- 所有 public 方法(length、capacity、setCharAt、reverse 等)都带
synchronized修饰符 - 锁对象是 StringBuffer 实例本身,即
this - 底层操作(如数组扩容、字符复制)由父类
AbstractStringBuilder完成,但入口控制在 synchronized 方法内 -
toStringCache是个优化字段,缓存上一次 toString() 的结果,避免重复构造字符串
底层存储与可变性是同步的前提
StringBuffer 本身不存字符,它继承自 AbstractStringBuilder,真正干活的是其中的:
Java Maven 项目审查工作流的通用输入处理。当 Java Maven 项目以 ZIP压缩包或 GitLab 仓库 URL 形式提供且需要...时使用。
char[] value;
int count;
这两个字段都不是 final,也不私有到不可触达——它们被设计为可动态修改:
-
value数组会随内容增长而扩容(策略通常是old * 2 + 2) -
count记录当前有效字符数,每次 append 后递增 - 如果没有同步保护,多个线程同时调用 append 就可能造成
count错乱、数组越界或数据覆盖
和 StringBuilder 的区别就这一行代码
对比 StringBuilder 的同名方法:
@Override
public StringBuilder append(String str) {
super.append(str);
return this;
}
唯一差别就是少了 synchronized。两者共享同一套 AbstractStringBuilder 底层逻辑,包括扩容、字符拷贝、缓存清理等——安全与否,全由这一个关键字决定。
性能代价来自锁竞争而非逻辑本身
同步本身不慢,慢在多线程争抢同一把锁:
- 单线程下,StringBuffer 比 StringBuilder 慢约 80% 以上(实测 100 万次 append)
- 4 线程并发时,StringBuffer 虽能正确运行,但吞吐量远低于使用
ThreadLocal<StringBuilder>或ConcurrentStringBuilder(JDK14+)的方案 - 锁粒度是整个对象,哪怕两个线程操作完全无关的 StringBuffer 实例,也不会互相影响;但若共用一个实例,就会串行化

















