stringbuffer仅保证单个方法的线程安全,不协调多方法调用顺序;其每个public方法均加synchronized锁,但多个方法组合操作非原子,需外部同步控制。

StringBuffer 本身不协调线程操作顺序,它只保证单个方法调用的线程安全,不控制多个方法之间的执行时序。
线程安全 ≠ 操作顺序协调
StringBuffer 的每个 public 方法(如 append()、insert()、delete())都用 synchronized 修饰,这意味着同一时刻只有一个线程能执行某个方法。但多个线程连续调用多个方法时,执行顺序仍由 JVM 线程调度器决定,StringBuffer 不干预也不保证整体逻辑顺序。
- 例如:线程 A 调用 append("A") 后立即调用 append("B"),线程 B 在中间插入 append("X"),结果可能是 "AX"、"XA" 或 "AXB",取决于调度时机
- StringBuffer 不提供“原子组合操作”(如“先删后加”作为一个不可分割单元),这类逻辑需外部同步控制
需要协调顺序时,必须显式加锁
若业务要求多个 StringBuffer 操作按特定顺序执行(比如“清空 + 追加 + 截取”必须原子完成),不能依赖 StringBuffer 自身,而要将整个操作块包裹在 synchronized 块中,锁对象通常是 StringBuffer 实例本身或统一的锁对象。
- 推荐方式:synchronized (sb) { sb.delete(0, sb.length()); sb.append(data); }
- 避免使用 synchronized (this) 在非 final 对象上,以防锁对象被替换导致失效
- 若涉及多个共享资源(如 StringBuffer + 外部计数器),应使用同一把锁,否则仍存在竞态
更现代的替代思路
StringBuffer 是早期为线程安全设计的类,如今多数场景建议:
- 优先使用 StringBuilder + 显式同步(更轻量,避免无谓开销)
- 对简单拼接,考虑 ThreadLocal
,彻底规避共享与锁 - 高并发下频繁修改字符串,可评估是否该用不可变结构(如构建过程用 List
收集,最后 join)或并发容器
小结:别指望 StringBuffer 排队
它只是给每个方法上了锁,像给每扇门装了独立门锁,但不负责安排谁先进门、进哪扇门、进门后做什么。真正需要顺序协调,得靠你自己的锁和设计。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











