stringbuffer线程安全靠synchronized方法实现,其append、insert等公开修改方法均加锁,确保同一实例上多线程操作串行执行,并提供原子性、可见性与有序性保障。

StringBuffer 的线程安全靠 synchronized 方法实现
StringBuffer 从 Java 1.0 就存在,它的所有公开修改方法(如 append、insert、delete、reverse)都用 synchronized 修饰。这意味着每次调用这些方法时,当前线程必须先获取该 StringBuffer 实例对象的锁(即 this 锁),执行完再自动释放。多个线程竞争同一 StringBuffer 实例时,只能串行执行,从而避免数据错乱。
synchronized 在 StringBuffer 中的具体表现
以 append(String str) 方法为例:
- 方法签名是 public synchronized StringBuffer append(String str)
- 字节码层面带 ACC_SYNCHRONIZED 标志,由 JVM 直接识别并加锁
- 锁对象始终是当前 StringBuffer 实例(this),不是类、也不是其他变量
- 内部还维护一个 toStringCache 字段,用于缓存 toString() 结果,减少重复构造字符串的开销
它为什么能保证线程安全?三个关键保障
synchronized 不只是“排队执行”,它同时提供三重语义保障:
-
原子性:像
count++这类非原子操作,在同步块内变成不可分割的整体,不会被其他线程打断 - 可见性:线程进入同步块前,会从主内存重新读取共享变量(如 value 数组、count);退出时,把修改强制刷回主内存,确保其他线程立即看到最新值
- 有序性:禁止编译器和处理器对同步块内的指令做重排序,也通过 happens-before 规则约束跨线程执行顺序
实际使用中的注意事项
虽然 StringBuffer 线程安全,但并不意味着“无脑用”:
- 单线程场景下,StringBuilder 性能更好——它功能几乎一样,但所有方法都不加锁
- JIT 编译器会对连续调用(如多次 append)做 锁消除 或 锁粗化,但这是优化结果,不能替代合理设计
- 如果只读不写,或每个线程操作不同 StringBuffer 实例,就不需要 synchronized 保护
- 若需更高并发能力(比如大量线程频繁拼接),应考虑 ConcurrentHashMap 配合局部 StringBuilder,而非依赖 StringBuffer 全局串行
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











