单线程用 stringbuilder,多线程共享同一对象才用 stringbuffer;两者均比 string 拼接高效,核心区别在于同步锁——stringbuilder 无锁、性能高10%–15%,stringbuffer 加 synchronized、线程安全但较慢。

直接看场景选:单线程用 StringBuilder,多线程共享同一对象才用 StringBuffer。两者都比用 + 拼接 String 快得多,核心差别就在“要不要锁”。
什么时候该用 StringBuilder
绝大多数日常开发都属于这个范畴——方法内局部变量、循环拼接 SQL/JSON/日志、模板生成等。它不加锁,操作都在一个线程里完成,性能比 StringBuffer 高 10%–15%。
- 声明时可预估长度:比如拼接结果大概 200 字符,写
new StringBuilder(200),避免多次数组扩容 - 常用操作就是
append()(追加)、insert()(插入)、delete()(删段)、reverse()(翻转),最后调toString()得到 String - 别把它传给多个线程共用——没同步机制,结果可能错乱
什么情况下必须用 StringBuffer
只有当多个线程会同时读写同一个 StringBuffer 实例时,才需要它。例如:全局缓存构建器、某些老式 Servlet 共享的格式化工具类。
- 它的
append、insert等关键方法都带synchronized,天然线程安全 - 但锁带来开销,同样操作下比 StringBuilder 慢,所以别为“以防万一”而滥用
- 如果只是多个线程各自 new 自己的 StringBuffer,那其实和 StringBuilder 效果一样,纯属多花开销
别踩这些常见坑
很多人误以为“StringBuffer 更稳”,结果在 Web 后端 Controller 方法里用它,其实完全没必要——每个请求都是独立线程,局部变量根本不会被其他线程访问。
- 循环里用
String += "xxx"是最大性能杀手,JVM 虽对简单拼接做了优化,但复杂逻辑或大量迭代仍会爆炸式创建对象 - 不要在工具类里暴露可变的 StringBuffer/StringBuilder 实例作为静态字段,除非你明确控制了并发访问
- String 本身适合常量、配置项、少量拼接;频繁修改就换可变类型,三者分工清晰
一句话总结用法
写代码时默认敲 StringBuilder,IDE 甚至会主动提示替换 + 拼接;只有当你画出线程交互图、确认真有多个线程抢同一个实例,才换成 StringBuffer。不复杂但容易忽略。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











