string拼接慢因每次+都新建对象;stringbuilder单线程最快,无锁无拷贝;stringbuffer多线程安全但有同步开销;少量拼接用string更优;预设容量可避免扩容损耗。

直接看性能表现,关键不是背结论,而是理解三者在不同操作模式下的真实开销。String 拼接慢不是因为它“差”,而是每次 + 都在新建对象;StringBuffer 和 StringBuilder 的差距也不在功能,而在同步锁是否被触发。
单线程下频繁拼接:StringBuilder 明显领先
这是最常见的场景,比如循环生成日志、构建 SQL 或 JSON 字符串。StringBuilder 底层用可扩容的 char[],所有操作(append、insert)都直接修改原数组,无锁、无拷贝开销。
- 10 万次追加字符串,StringBuilder 通常耗时 1–3ms
- 同样操作,String 的
+=会创建 10 万个中间对象,耗时常达 200–500ms(JVM 垃圾回收压力也显著上升) - StringBuffer 因每个
append都带synchronized,耗时约是 StringBuilder 的 1.3–1.8 倍
多线程共享同一实例:只有 StringBuffer 安全可用
如果多个线程共用一个字符串构建器(例如全局日志缓冲区),String 和 StringBuilder 会出错——字符乱序、长度错位、甚至 ArrayIndexOutOfBoundsException。StringBuffer 的方法级同步能保证数据一致性,但代价是性能下降。
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
- 10 个线程并发执行 1 万次
append,StringBuffer 耗时约是单线程同操作的 2.5–4 倍(锁竞争加剧) - StringBuilder 在此场景下结果不可预测,不能用于生产
- String 虽线程安全,但每次拼接都新建对象,内存和 GC 压力远超前两者,实际不适用
少量拼接或仅读取:String 反而更优
当字符串只拼接 1–2 次,或主要用于存储/传递/作为 Map 键时,String 的不可变性成了优势:无扩容逻辑、无对象生命周期管理、可复用常量池引用、hashCode 可缓存。
-
String a = "hello" + " world"在编译期就被优化为字面量,零运行时开销 -
map.put("user_id", userId)用 String 作键,比用 StringBuilder.toString() 更安全、更轻量 - 大量短字符串临时拼接(如模板渲染中 3–5 次内),JVM 的字符串压缩(JDK 9+ byte[])和逃逸分析可能让 String 表现接近 StringBuilder
扩容行为影响实际吞吐:预设容量很关键
StringBuilder 和 StringBuffer 都基于数组,初始容量默认为 16。若拼接内容远超预期,反复扩容(复制旧数组 → 分配新数组 → 拷贝)会吃掉近 30% 性能。
- 已知最终长度约 200 字符,建议构造时指定:
new StringBuilder(256) - 避免用
new StringBuilder().append(a).append(b).append(c)这种链式调用却不预估容量的方式 - String 没有扩容概念,但频繁
concat或+会不断触发数组拷贝(每次都要复制全部已有内容)
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










