stringbuffer线程安全靠所有修改方法加synchronized锁住this实现串行化,但仅保障单方法原子性;多步操作需手动加锁,而stringbuilder无同步、单线程性能更高。

Java StringBuffer 的线程安全不是靠“自动防护”,而是靠每个修改方法都加 synchronized,锁住当前实例本身(this),让多线程对同一对象的操作强制串行化——但仅限单个方法调用有效。
同步怎么生效:方法级锁 + JVM 支持
StringBuffer 所有公开修改方法(如 append()、insert()、delete()、reverse())都声明为 public synchronized。这意味着:
- 每次调用时,线程必须先获取该 StringBuffer 实例的对象锁(即
this) - 同一时刻,只有一个线程能执行该实例上的任意一个同步方法
- 其他线程若尝试调用,会被阻塞,直到锁释放
- 字节码层面带
ACC_SYNCHRONIZED标志,由 JVM 直接识别并管理,无需手动写synchronized块
线程安全的真正边界在哪
它只保单个方法的原子性,不保多步逻辑。以下情况仍可能出错:
Java JDK 25 来自 OpenJDK 官方归档,版本为 JDK 25,本条下载地址已指向官方 Windows x64 zip 安装包直链,适合调试旧项目或兼容旧版 Java 运行环境。
-
检查后使用(check-then-act):比如
if (sb.length() ,两行之间 sb 可能已被其他线程修改 -
读-改-写序列:如先读
len = sb.length(),再执行sb.delete(0, len/2),中间len已失效 - toString() 后续操作:返回的是新 String 对象,与原 sb 锁无关;对该 String 的任何修改都不受保护
这类场景必须显式加锁:synchronized(sb) { ... }
和 StringBuilder 的本质区别
二者 API 完全一致,底层同继承 AbstractStringBuilder,共享扩容逻辑(默认容量 16,扩容公式为 2×旧容量+2)。关键差异只有同步策略:
-
StringBuffer:所有修改方法加
synchronized,适合多线程共享写入(如日志聚合器、全局配置拼接) - StringBuilder:无任何同步,单线程下性能高约 80%–100%,是局部变量拼接(如 SQL 构建、JSON 生成)的默认选择
实际选型建议
别因“线程安全”就默认选 StringBuffer。应按真实场景判断:
- 真需多个线程并发修改同一个可变字符串 → 用 StringBuffer
- 方法内局部使用、或单线程环境 → 必须用 StringBuilder
- 高并发拼接且想避免串行瓶颈 → 改用
ThreadLocal<stringbuilder></stringbuilder>或用并发队列收集再合并 - 仅需简单拼接、无状态逻辑 → 优先考虑
String.join()、Collectors.joining()等不可变方案
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










