stringbuilder与stringbuffer核心差异在于线程安全性与性能:前者非线程安全、无synchronized开销,单线程下快10%–20%;后者所有公共方法加synchronized,保障多线程安全但有同步损耗;二者均继承abstractstringbuilder,底层均为可变char[](jdk9+为byte[]),扩容策略与api完全一致。

StringBuilder 和 StringBuffer 的核心差异就两点:线程安全性和性能表现。其余功能、API、底层结构几乎完全一致,选哪个主要看运行环境是否涉及多线程共享操作。
线程安全性:同步锁是唯一本质区别
StringBuffer 所有公共修改方法(如 append、insert、delete)都加了 synchronized 关键字,保证多线程调用时不会出现数据错乱;StringBuilder 完全不加锁,同一对象被多个线程并发修改时,结果不可预测,可能抛出异常或生成错误字符串。
这个设计不是疏忽,而是明确取舍:StringBuffer 为线程安全付出同步开销,StringBuilder 则默认信任单线程上下文,把性能做到极致。
性能表现:单线程下 StringBuilder 明显更快
在纯单线程场景中,StringBuilder 比 StringBuffer 快约 10%–20%,差距来自 synchronized 锁的获取、检查与释放过程——即使当前只有单个线程,JVM 仍需执行轻量级锁相关逻辑(如偏向锁校验、锁计数更新等)。
实测常见拼接循环(如万次 append)中,StringBuilder 耗时通常稳定在 StringBuffer 的 80% 左右。这种差距在高吞吐服务(如日志组装、JSON 构建)中会放大为可观的 CPU 节省。
底层实现:共享 AbstractStringBuilder,数组可变
二者都继承自 AbstractStringBuilder,底层使用非 final 的 char[] value(JDK 9+ 优化为 byte[] + 编码标识),支持原地扩容与内容修改。
Java项目代码review工具。分析Git变更+完整调用链路上下文,推断业务需求,进行多维度评分和分类汇总,生成完整PRD文档。包含细粒度Java代码审查清单(Null安全、异常处理、Streams、并发、equals/hashCode、资源管理、API设计、性能、MyBatis/ORM、事务边界、SQL/DD...
扩容策略相同:初始容量 16,当字符数超过当前容量时,新容量 = 旧容量 × 2 + 2;所有增删改操作最终都通过 System.arraycopy 复制数组完成。
StringJoiner 内部也封装了 StringBuilder,所以它同样是非线程安全、高性能的,专用于带分隔符的拼接(如 "a,b,c" 或 "[x, y, z]")。
怎么选:看场景,不看习惯
用 StringBuilder 的情况:
- Web 后端接口内拼 SQL、JSON、HTTP 响应体
- 工具类中格式化日期、路径、消息文本
- 单元测试里构造测试数据
- 任何明确只在一个线程中使用的字符串构建逻辑
用 StringBuffer 的情况:
- 全局日志缓冲器(被多个业务线程共用)
- 遗留系统中无法重构线程模型的共享字符串容器
- 极少数需要跨线程传递并持续修改的字符串对象(现代开发中已较少见)
不建议混用:不要因为“听说 StringBuffer 更老更稳”就在单线程里用它,也不该为了省事把 StringBuilder 当共享变量扔进线程池任务中。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










