stringbuffer通过在所有公共修改方法(如append、insert、delete、reverse)上加synchronized实现线程安全,锁对象为this实例,确保同一时刻仅一个线程执行这些操作,但不保证多步组合操作的原子性。

StringBuffer 通过在所有修改方法上加 synchronized 关键字实现线程安全。 它的每个公共可变操作(如 append、insert、delete、reverse)都是同步方法,确保同一时刻只有一个线程能执行这些操作,从而避免多线程并发修改导致的数据不一致问题。
核心机制:方法级同步
StringBuffer 继承自 AbstractStringBuilder,但所有会改变内部字符数组(value)的方法都被声明为 synchronized:
public synchronized StringBuffer append(String str)public synchronized StringBuffer insert(int offset, String str)public synchronized void setCharAt(int index, char ch)public synchronized StringBuffer reverse()
这意味着每次调用这些方法时,当前 StringBuffer 实例对象本身作为锁,其他线程必须等待当前线程释放锁后才能进入。这种粗粒度同步简单有效,但可能带来性能开销。
与 StringBuilder 的关键区别
StringBuilder 提供了完全相同的 API,但所有方法都不加 synchronized,因此非线程安全,但单线程下性能更高(无同步开销)。选择依据很直接:
- 多线程共享同一个缓冲区 → 用 StringBuffer
- 单线程或局部变量使用 → 用 StringBuilder(推荐)
注意:StringBuffer 并不保证“组合操作”的原子性。例如 sb.append("a").append("b") 是两次同步调用,中间仍可能被其他线程插入操作——如需完整逻辑原子性,需手动加锁或改用更高层同步策略。
内部实现细节补充
StringBuffer 底层仍使用 char 数组(value)和长度(count)管理内容,扩容逻辑与 StringBuilder 一致(自动翻倍+1)。不同的是,所有涉及 count 修改或 value 写入的操作都被同步保护,包括扩容时的数组复制过程。
它还重写了 toString() 方法,返回新创建的 String 对象(内容不可变),该方法也是 synchronized,确保返回结果反映调用时刻的一致快照。
实际使用建议
除非明确需要多线程共享并修改同一个 StringBuffer 实例,否则优先使用 StringBuilder。现代 Java 开发中,更常见的做法是:
- 用局部 StringBuilder 构建字符串(线程内安全、高效)
- 若需跨线程传递字符串结果,直接传 final String,而非共享可变缓冲区
- 真有复杂并发拼接需求(如日志聚合),考虑使用
ConcurrentHashMap+ 分段锁,或异步队列,而不是依赖 StringBuffer 的同步粒度
StringBuffer 是 Java 早期为线程安全提供的简单解法,理解其原理有助于权衡场景,但不必过度依赖。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











