优化 synchronized 的核心是降低锁竞争、缩短临界区、避免升级和缩小同步范围;优先用细粒度锁、CAS 原子类、读写锁等替代方案,并结合 JVM 工具监控锁瓶颈。

减少 synchronized 带来的线程阻塞,核心不是“去掉锁”,而是降低锁竞争强度、缩短临界区、避免锁升级和减少无谓的同步范围。
缩小 synchronized 作用范围
只对真正需要保护的代码加锁,避免把日志、对象创建、IO 等非共享操作包进同步块。
- 把
synchronized(this)改为synchronized(lockObj)(细粒度锁对象),让不同业务逻辑使用不同锁 - 避免在 getter/setter 这类简单方法上直接加 synchronized——若字段本身是线程安全的(如
AtomicInteger),可完全去除 - 示例:原写法
public synchronized void update() { log.info(...); counter++; }→ 提取临界操作:counter++单独用锁保护,日志移出同步块
用更轻量的并发工具替代
JDK 提供了比内置锁更高效、更灵活的替代方案,尤其适合高并发读多写少或计数类场景。
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
- 读多写少:用
ReentrantReadWriteLock,允许多个读线程并发,仅写操作互斥 - 简单计数/状态更新:优先用
AtomicInteger、AtomicReference等 CAS 操作,无锁且性能高 - 复杂状态管理:考虑
StampedLock(支持乐观读),在低冲突场景下吞吐更高 - 注意:
ConcurrentHashMap等线程安全集合内部已做分段/锁分离优化,不要在外层再套 synchronized
监控锁竞争并识别瓶颈点
盲目优化可能适得其反。需借助 JVM 工具确认是否真由 synchronized 导致阻塞。
立即学习“Java免费学习笔记(深入)”;
- 用
jstack -l <pid>查看线程堆栈,重点关注- waiting to lock <0x...>和- locked <0x...>的配对,定位热点锁对象 - 开启 JVM 参数
-XX:+PrintGCDetails -XX:+PrintSafepointStatistics -XX:PrintSafepointStatisticsCount=1辅助判断是否因锁导致 safepoint 停顿加剧 - JFR(Java Flight Recorder)录制中关注
java.monitor-enter事件的平均阻塞时间与频率,直观识别长等待锁
避免锁膨胀与不必要的锁升级
HotSpot JVM 对 synchronized 有锁升级机制(无锁 → 偏向锁 → 轻量级锁 → 重量级锁),一旦升级到重量级锁,就会触发 OS mutex,开销陡增。
- 若确定多线程高频竞争,可加
-XX:-UseBiasedLocking关闭偏向锁(JDK 15+ 默认关闭) - 避免在循环内反复进入同一 synchronized 块;若循环体必须同步,考虑将整个循环逻辑移到同步块内,减少进出次数
- 注意锁对象生命周期:长期存活且被多线程争用的对象(如单例 service 实例)更容易触发重量级锁,可考虑用对象池或局部锁对象替代

















