偏向锁是synchronized锁升级路径的第一级优化,专为单线程反复进入同一同步块设计,通过对象头记录线程id实现零成本重入,避免cas等开销;一旦发生竞争则触发需stw的偏向撤销并不可逆升级为轻量级锁。

偏向锁是 synchronized 锁升级路径中的第一级优化,专为“单线程反复进入同一同步块”场景设计。它不是万能的,但用对地方能显著降低无竞争时的开销。
偏向锁的优点
核心优势在于零成本重入:同一个线程后续再次获取锁时,无需任何 CAS 或内存屏障操作,仅需比对对象头中记录的线程 ID 是否匹配,毫秒级甚至纳秒级完成。
- 加锁/解锁开销极小,几乎等同于执行非同步方法
- 避免了轻量级锁所需的 CAS 操作和栈帧锁记录分配
- 在初始化、配置加载、单线程批处理等场景下,性能接近无锁
偏向锁的缺点
它的弱点也很明确——不适应多线程竞争。一旦出现其他线程争抢,就得触发“偏向撤销”,这个过程代价不小。
- 偏向撤销必须等待全局安全点(SafePoint),会暂停所有应用线程,带来 STW 开销
- 撤销后直接升级为轻量级锁,原偏向状态不可恢复,且整个对象后续再无法进入偏向状态
- 在高并发或频繁切换持有者的场景下(如 Web 请求线程池复用),反而因频繁撤销导致 CPU 和延迟上升
偏向锁适用的典型场景
判断标准很简单:看同步块是否长期由同一个线程独占。
- 单例对象的初始化逻辑(如 Spring Bean 构造后的首次 set 方法调用)
- 线程局部缓存(ThreadLocal 相关结构内部同步)
- 定时任务中固定由某调度线程执行的同步操作
- 日志框架中 Appender 的内部状态更新(若由固定线程驱动)
如何确认是否启用及是否生效
默认开启(JDK 6+),但可通过 JVM 参数控制:
- -XX:+UseBiasedLocking 启用(默认);-XX:-UseBiasedLocking 禁用
- -XX:BiasedLockingStartupDelay=0 可取消启动延迟(默认 4 秒),让偏向锁更早生效
- 配合 -XX:+PrintSafepointStatistics -XX:PrintSafepointStatisticsCount=1 观察撤销次数,辅助诊断
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











