stringbuffer通过在append()、insert()、delete()、reverse()、tostring()、length()等所有public方法上加synchronized锁住this实例,保障单方法原子性;但跨方法组合操作(如check-then-act)需显式synchronized(sb)保护。

StringBuffer 通过在每个公开修改方法上加 synchronized 关键字,锁住当前实例对象(this),强制多线程对同一实例的操作串行化,从而保障基本线程安全。
同步锁作用在哪些方法上
所有可能改变内部状态的 public 方法都带有 synchronized 修饰,包括:
- append()、insert()、delete()、reverse()
- 连 toString() 和 length() 这类看似只读的方法也同步——为的是保护内部缓存(如 toStringCache)和字段(如 count)的一致性
- 底层共享 AbstractStringBuilder,扩容、数组复制、长度更新等动作全部包裹在同步块内,不会被中断
锁的粒度是实例级,不是全局
它用的是对象锁(this 锁),不是 static 或 Class 级锁。这意味着:
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
- 两个不同的 StringBuffer 实例(如 sb1 和 sb2)可被多个线程同时操作,互不干扰
- 只有操作同一个实例的多个线程才会竞争同一把锁,符合“最小保护范围”原则
- 避免了过度串行化,比类锁更合理、更轻量
单方法原子性有保障,但组合操作不自动安全
同步机制只确保单次方法调用的完整性,比如一次 append() 不会中途被覆盖或错乱。但它不延伸到跨方法逻辑:
- if (sb.length() 是两步独立同步调用,中间可能被其他线程修改 sb
- sb.charAt(i); sb.setCharAt(i, 'x') 同样存在竞态,需手动用 synchronized(sb) { ... } 包裹
- toString() 返回的是新 String 对象,后续对该 String 的任何操作都不再受 StringBuffer 锁保护
性能代价来自锁本身的开销
即使没有线程争抢,synchronized 方法仍要执行 monitor enter/exit、内存屏障、锁状态检查等 JVM 操作:
- 单线程下,StringBuffer 拼接比 StringBuilder 慢约 80%–100%
- 链式调用(如 sb.append("a").append("b"))反复进出锁,开销叠加
- 高并发时,锁竞争导致线程阻塞、上下文切换频繁,吞吐量明显下降
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










