选stringbuilder还是stringbuffer取决于线程环境:单线程用stringbuilder性能更优,多线程共享实例时必须用stringbuffer保证线程安全,二者api一致但stringbuffer方法加synchronized锁而stringbuilder无锁。

选 StringBuilder 还是 StringBuffer,关键不在方法名是否一样,而在于“谁在用、怎么用”。两者 API 高度一致,几乎所有公开方法(append、insert、delete、replace、reverse、toString等)签名完全相同,但行为背后有本质区别。
方法功能几乎一模一样
从使用角度看,两者都提供可变字符串操作能力:
- append():支持任意类型参数(String、int、boolean、char[] 等),自动转为字符串拼接
- insert(int offset, ...):在指定位置插入内容,下标从 0 开始
- delete(int start, int end):删除 [start, end) 区间字符(左闭右开)
- replace(int start, int end, String str):用新字符串替换指定区间
- reverse():原地反转整个序列
- toString():返回当前内容的不可变 String 副本
写法上基本可以互换,比如 sb.append("a").append(123).reverse() 在两者中都能正常运行。
核心差异全在方法实现上
表面一致,底层完全不同:
-
StringBuffer 的每个公开方法都加了
synchronized—— 方法级锁,保证多线程调用时不会出现数据错乱。例如append()内部所有修改 char[] 的逻辑都被锁住 - StringBuilder 完全不加锁 —— 同样方法名,但执行路径更短、无同步开销,单线程下性能通常高出 3–4 倍
- 两者都继承自
AbstractStringBuilder,共享大部分逻辑代码,仅同步机制是唯一实质性差异
构造方式和容量管理也一致
初始化和扩容策略完全相同:
-
new StringBuilder()和new StringBuffer()都默认分配 16 字符容量 -
new StringBuilder(String s)和new StringBuffer(String s)都以 s.length() + 16 为初始容量 - 当内部 char[] 不够用时,两者都采用「当前长度 × 2 + 2」的扩容公式
- 都支持
ensureCapacity(int)主动预设容量,避免频繁扩容
什么时候该用哪个?看线程环境
不是看功能强弱,而是看并发需求:
- 单线程场景(如 Web 请求内构建 SQL、JSON、日志消息)→ 选 StringBuilder,性能更好,无锁更轻量
- 多线程共享同一实例(如全局配置生成器、静态工具类中的缓存拼接器)→ 必须用 StringBuffer,否则可能产生脏数据或 ArrayIndexOutOfBoundsException
- 若能确保线程隔离(比如每个线程 new 自己的实例)→ 即便用 StringBuffer 也没问题,但没必要,浪费同步成本
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











