stringbuilder多线程下不安全,stringbuffer安全——因stringbuilder方法无synchronized修饰,多线程并发调用append等会导致数据覆盖、字符数组错位、结果不可预测;stringbuffer所有公共修改方法均被synchronized修饰,确保同一时刻仅一锁线程执行,保障操作原子性。

StringBuilder 在多线程下不安全,StringBuffer 在多线程下安全——这是由底层同步机制决定的,不是“能不能用”,而是“用了会不会出错”。
StringBuilder 多线程访问会出什么问题
多个线程同时调用同一个 StringBuilder 实例的 append()、insert() 等方法,会导致:
- 数据丢失或覆盖:比如两个线程同时执行 append("a"),预期长度 +2,实际可能只 +1;
- 字符数组越界或错位:内部 count 值被并发修改,导致写入位置错误;
- 结果不可预测且无异常抛出:不会直接报 ConcurrentModificationException,但输出内容随机、长度异常,极难复现和调试。
StringBuffer 为什么能保证线程安全
它的所有公共修改方法(append、insert、delete、reverse 等)都加了 synchronized 修饰符,意味着:
- 同一时刻只有一个线程能进入该方法体;
- 方法内对 char[] value 和 int count 的读写是原子的、受锁保护的;
- 即使 10 个线程并发调用 append(),最终结果也严格等价于串行执行(如顺序拼接 10 次 "a" 得到 "aaaaaaaaaa")。
别以为加了 synchronized 就万无一失
StringBuffer 的线程安全仅限于单个方法调用。如果业务逻辑需要多个操作组成原子动作,它依然无法保障:
- 例如:if (sb.length() —— 这个判断+追加不是原子的,其他线程可能在中间插入操作;
- 此时需额外加锁(如 synchronized(sb) {...}),或改用更高级的并发工具(如 ThreadLocal
)。
实际开发中更推荐的多线程方案
多数场景下,并不真需要共享一个 StringBuffer 实例:
- 用 ThreadLocal
:每个线程独享实例,无锁、高性能、避免竞争; - 用 StringJoiner 或 String.format:适合固定格式拼接,天然无状态;
- 用 ConcurrentHashMap + 分段拼接:大数据量日志合并时,按 key 分组后各自 StringBuilder 拼完再汇总;
- 只有极少数必须共享缓冲区的场景(如全局日志聚合器),才考虑 StringBuffer,并配合外部同步控制。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











