StringBuilder与StringBuffer的核心区别是线程安全性:StringBuffer方法加synchronized,线程安全但性能低;StringBuilder无同步,单线程下快10%–20%,多线程需外部同步。

StringBuilder 和 StringBuffer 的核心区别在于线程安全性:StringBuffer 是线程安全的,StringBuilder 不是。这意味着在多线程环境下直接共享使用 StringBuffer 更安全,而 StringBuilder 仅适用于单线程或已由外部同步保护的场景。性能上,StringBuilder 通常更快,因为它省去了同步开销。
线程安全性与内部实现
StringBuffer 的大多数公共方法(如 append、insert、reverse)都用 synchronized 关键字修饰,保证同一时刻只有一个线程能执行这些操作;StringBuilder 对应方法则完全不加锁。这种设计差异直接决定了它们的适用边界——不是“谁更好”,而是“谁更合适”。
性能表现差异
在纯单线程场景下,StringBuilder 的吞吐量普遍比 StringBuffer 高 10%–20%,尤其在频繁拼接字符串时差距更明显。例如循环追加 10 万次字符串,StringBuilder 可能快几十毫秒。但若强行在多线程中使用 StringBuilder 而未加锁,可能引发数据错乱(如部分字符丢失、顺序混乱),这类 bug 很难复现和调试。
API 兼容性与替换建议
两者 API 几乎完全一致,继承自同一个抽象类 AbstractStringBuilder,所以代码迁移成本极低。建议按以下原则选择:
立即学习“Java免费学习笔记(深入)”;
- 明确只在单线程中使用(如局部变量、方法内构建字符串)→ 优先选 StringBuilder
- 对象会被多个线程共享且无额外同步措施 → 必须用 StringBuffer
- 已有 StringBuffer 代码但确认无并发访问 → 可安全替换为 StringBuilder 提升性能
实际开发中的常见误用
一个典型误区是认为“只要用了 synchronized 就绝对安全”。实际上,StringBuffer 仅保证单个方法调用的原子性,不保证复合操作的线程安全。例如:
if (sb.length() == 0) sb.append("default");
这段代码即使用 StringBuffer,在多线程下仍可能出错——因为 length() 和 append() 是两个独立同步方法,中间可能被其他线程修改状态。此时仍需外层加锁或改用其他并发策略。










