选型关键看是否多线程共享修改同一个实例:若多线程并发操作同一对象,必须用 StringBuffer;否则优先选 StringBuilder。StringBuffer 线程安全但性能低,StringBuilder 高效但仅适用于单线程或独占实例场景。

选型关键看是否多线程共享修改同一个实例:如果多个线程会同时调用 append、insert、delete 等方法操作同一个对象,必须用 StringBuffer;否则优先选 StringBuilder。
StringBuffer 是线程安全的,但代价是性能开销
StringBuffer 的几乎所有可变操作(如 append()、reverse()、setCharAt())都加了 synchronized 修饰,保证同一时刻只有一个线程能执行这些方法。这在多线程环境下避免了数据错乱,比如两个线程同时 append("a") 和 append("b"),结果一定是 "ab" 或 "ba",不会出现字符交错或越界异常。
- 适合场景:被多个线程共享且频繁修改的字符串构建器(例如作为静态工具类字段、被注入到多个线程任务中)
- 注意:同步粒度较粗,单个方法全程锁住整个对象,高并发下易成瓶颈
StringBuilder 非线程安全,但性能更好
StringBuilder 方法没有同步机制,所有操作直接操作内部字符数组。在单线程或每个线程独占一个实例时,它比 StringBuffer 快 10%–15%(JDK 8+ 测试典型场景)。它的设计初衷就是“本地使用”——方法内创建、用完丢弃,不跨线程传递。
Java项目代码review工具。分析Git变更+完整调用链路上下文,推断业务需求,进行多维度评分和分类汇总,生成完整PRD文档。包含细粒度Java代码审查清单(Null安全、异常处理、Streams、并发、equals/hashCode、资源管理、API设计、性能、MyBatis/ORM、事务边界、SQL/DD...
- 适合场景:局部变量、方法参数、流式构建(如
new StringBuilder().append(...).toString()) - 错误用法举例:把
StringBuilder设为类的static字段,又被多个线程调用append—— 会出现内容丢失、ArrayIndexOutOfBoundsException或乱序
实际选型建议:先看生命周期和作用域
别从“要不要线程安全”出发,而要问:“这个对象会不会被多个线程看到并修改?”
立即学习“Java免费学习笔记(深入)”;
- 局部变量(方法内 new)→ 无脑用
StringBuilder - 作为参数传入,且只被当前线程使用 →
StringBuilder - 作为类成员变量,且该类实例会被多个线程共用 → 检查是否会被并发修改;若是,改用
StringBuffer或重构为不可变/线程局部存储 - 不确定?加单元测试模拟多线程调用,观察结果是否稳定;不稳定就换
StringBuffer或加外部同步
替代方案:比 StringBuffer 更轻量的线程安全选择
如果只是需要多线程拼接、最终汇总结果,不一定非要共享一个对象:
- 用
StringBuilder在各线程中独立构建,最后用Collectors.joining()或String.join()合并结果 - 用
ThreadLocal<stringbuilder></stringbuilder>为每个线程分配专属实例,避免竞争又免去同步开销 - 纯拼接场景(无复杂逻辑),考虑
StringJoiner或直接用String.concat()/+(编译器优化后效率接近)

















