单线程优先用stringbuilder,因其功能与stringbuffer几乎一致但无synchronized开销,性能高10%–15%;多线程共享同一对象时才必须用stringbuffer,因其方法均加锁保障线程安全。

单线程场景下优先用 StringBuilder,多线程共享同一对象时才考虑 StringBuffer。
单线程中为什么选 StringBuilder
它和 StringBuffer 功能几乎完全一致,但所有方法都不加锁,避免了同步开销。在字符串拼接、插入、删除等频繁操作中,性能明显更高。
- 比如循环拼接 10 万次字符串,StringBuilder 耗时通常只有 StringBuffer 的 60%–70%
- 内部基于可变 char 数组,append、insert 等操作直接修改原对象,不产生中间 String 对象
- JVM 对 StringBuilder 的优化更充分,例如编译器可能将 + 拼接自动转为 StringBuilder(仅限编译期确定的字符串)
多线程中为何必须用 StringBuffer
当多个线程同时读写同一个字符串缓冲区对象时,StringBuilder 会出现数据错乱或结果不可预期——因为它不保证方法调用的原子性。
- StringBuffer 的关键方法(如 append、delete、reverse)都用
synchronized修饰,确保同一时刻只有一个线程能执行 - 注意:StringBuffer 的线程安全只针对自身对象的操作,不保护你传入的外部参数(比如共享的 char[] 或 StringBuilder 实例)
- 如果只是多个线程各自创建独立的 StringBuffer 实例,也无需特别切换——此时用 StringBuilder 更合适
实际开发中的常见误判
很多开发者看到“多线程”就下意识选 StringBuffer,其实多数情况并不需要。
- Web 应用中每个请求通常由独立线程处理,每个线程内构建 SQL 或 JSON 用 StringBuilder 完全安全
- 线程池任务中若 StringBuffer 是局部变量(即每个任务 new 自己的),也不构成共享,仍推荐 StringBuilder
- 真正需要 StringBuffer 的典型场景:全局日志缓冲器、共享配置拼接器、被多个线程反复读写的缓存字符串对象
简单决策流程
判断是否共用同一个对象实例:
- 是 → 多线程访问 → 用 StringBuffer
- 否 → 各自持有独立实例 → 单线程行为 → 用 StringBuilder
- 不确定或想省心 → 且对性能不敏感 → 可用 StringBuffer,但不推荐作为默认习惯
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











