StringBuffer是线程安全的,因其所有关键方法(如append、insert、delete等)均用synchronized修饰,确保同一时刻仅一个线程能执行实例的同步方法,但多方法组合调用仍需手动加锁以防竞态。

Java 中 StringBuffer 的线程安全,本质是靠方法级 synchronized 实现的——每个修改操作都独占对象锁,避免多线程并发修改导致数据错乱。
为什么 StringBuffer 是线程安全的
StringBuffer 的关键公共方法(如 append、insert、delete、reverse、replace)全部被声明为 synchronized。这意味着:
- 每次调用这些方法时,线程必须先获取该 StringBuffer 实例自身的锁(
this) - 同一时刻,只有一个线程能执行该实例上的任意一个 synchronized 方法
- 其他线程若尝试调用,会被阻塞,直到锁被释放
- 底层基于
char[]数组和count字段,同步确保了数组扩容、索引更新、内容写入等步骤不被中断
线程安全的边界在哪里
单个方法调用是安全的,但多个方法组合使用时,仍可能出问题:
Java Maven 项目审查工作流的通用输入处理。当 Java Maven 项目以 ZIP压缩包或 GitLab 仓库 URL 形式提供且需要...时使用。
-
sb.length()和sb.append("x")是两个独立同步方法,中间可能被其他线程修改 sb - 典型的“检查后使用”(check-then-act)竞态:比如先判断长度是否为 0,再追加内容,这两步之间无原子性
- 此时需手动加锁:用
synchronized(sb) { ... }包裹整个逻辑块
与 StringBuilder 的核心区别
两者 API 完全一致,差异集中在并发控制层面:
立即学习“Java免费学习笔记(深入)”;
-
StringBuffer:所有修改方法加
synchronized,适合多线程共享场景,但性能开销明显(实测单线程下比 StringBuilder 慢约 80%) - StringBuilder:无任何同步,纯单线程优化设计,速度快,内存友好
- 若需在多线程中高效拼接,优先考虑
ThreadLocal<StringBuilder>或并行流 + 不可变字符串组合,而非全局共享 StringBuffer
实际使用建议
不必为了“线程安全”而默认选 StringBuffer:
- 绝大多数业务逻辑中,字符串拼接发生在单一线程内(如 Controller 层组装响应),直接用 StringBuilder 更合理
- 只有明确需要多个线程反复读写同一个可变字符串对象时,才选用 StringBuffer
- 注意初始容量设置(默认 16),避免频繁扩容影响性能;必要时用
new StringBuffer(128)预分配 - 调用
toString()后,StringBuffer 内部会缓存结果(toStringCache),提升重复调用效率

















