Java中StringBuffer和StringBuilder有什么区别_线程安全差异解析

StringBuffer线程安全但性能低,StringBuilder单线程高性能;二者API和底层实现一致,选择取决于是否存在并发写入场景。

线程安全是核心区别

StringBuffer所有公开方法都用 synchronized 修饰,天然支持多线程并发操作,不会出现数据错乱;StringBuilder完全不加锁,多个线程同时调用它的 appendinsert 等方法时,结果不可预测。

性能表现差异明显

同步机制带来开销,单线程环境下 StringBuilder 通常比 StringBuffer 快 5–15 倍。比如循环拼接 10 万次字符串,用 StringBuilder 可能耗时 2ms,而 StringBuffer 可能达到 20ms 以上。

  • StringBuffer 每次方法调用都要检查和获取锁
  • StringBuilder 直接操作底层 char 数组,无额外控制流
  • toString() 实现也不同:StringBuffer 复用缓存(toStringCache),StringBuilder 每次复制数组再构造新 String

功能几乎完全一致

两者都继承自 AbstractStringBuilder,共享全部核心 API:append、insert、delete、reverse、substring、capacity、length 等。代码从 StringBuffer 切换到 StringBuilder,通常只需改类名,无需调整逻辑。

  • 底层都是可修改的 char 数组
  • 都实现了 CharSequence 接口
  • 初始容量、扩容策略、字符操作行为完全相同

使用场景怎么选

不是看“要不要安全”,而是看“有没有并发写入”:

  • Web 后端中 DAO 层拼 SQL —— 单线程处理请求,用 StringBuilder
  • 日志工具类被多个线程共用且频繁追加内容 —— 必须用 StringBuffer
  • 局部变量做字符串组装(如方法内临时拼接)—— 一律 StringBuilder
  • 静态工具类中提供公共字符串处理方法且会被并发调用 —— 需评估是否加锁或改用 StringBuffer
JDK 5 引入 StringBuilder 就是为了填补 StringBuffer 在单线程下的性能缺口,不是替代,而是分工。