stringbuffer线程安全因其所有可变操作方法均用synchronized修饰,通过this锁串行化访问共享char[]和count;单个方法原子但组合逻辑需额外同步;与stringbuilder唯一区别是同步关键字,适用于多线程共用实例场景。

StringBuffer 在多线程环境下保持安全,是因为它的所有可变操作方法(比如 append、insert、delete、reverse)都用 synchronized 修饰,每次调用时自动获取该实例自身的锁(this 锁),确保同一时刻只有一个线程能执行这些方法。
靠方法级同步保护内部状态
它不靠“不可变”(那是 String 的方式),也不靠每次都新建对象(性能太差),而是通过锁住整个对象来串行化访问:
- 底层共享一个 char[] 数组(value)和一个整型计数器(count),所有读写都包裹在 synchronized 方法里
- 扩容、字符复制、索引更新等操作虽由父类 AbstractStringBuilder 完成,但入口已被同步控制
- 即使多个线程同时调用 append("A") 和 append("B"),也不会出现字符错位、数组越界或 count 错乱
线程安全有明确边界
单个方法调用是原子的,但组合逻辑仍需注意:
- length() 和 append() 是两个独立同步方法,中间可能被其他线程插入操作
- 像 “先判断长度再追加” 这类检查-后执行(check-then-act)逻辑,必须手动加锁:
synchronized(sb) { ... } - toString() 也是 synchronized,但返回的是新 String 对象,后续对该 String 的操作不再受锁保护
和 StringBuilder 的区别就一行代码
两者 API 完全一致,底层共用 AbstractStringBuilder,唯一差异就是 synchronized 关键字:
- StringBuilder 的 append 方法没有 synchronized,多线程共用会引发数据丢失、乱序甚至运行时异常
- StringBuffer 多线程下结果始终完整、可预期——不是顺序确定,而是内容不损坏
- 选错不会编译报错,但会在高并发时出现偶发性错误,极难复现
真正需要它的时候才用
它不是万能并发工具,适用场景很具体:
- 多个线程共用同一个实例持续拼接(如全局日志缓冲区、配置构建器)
- 老系统中已存在跨线程修改 StringBuffer 的设计,重构成本过高
- 线程数少(2–4 个)、吞吐不高、追求简单而非极致性能
- 若每个线程都 new 自己的 StringBuffer,那和 StringBuilder 没区别,还白背同步开销
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











