偏向锁是jvm对“几乎无竞争”场景的轻量标记优化,非真正加锁而是记名式占位;新对象默认无锁(mark word存哈希码等,标志位01),首次synchronized时通过一次cas写入线程id完成偏向,后续同线程访问仅需寄存器比对,零同步成本。

无锁状态到偏向锁的演变,本质是JVM对“几乎无竞争”场景的一次轻量标记优化,不是真正加锁,而是提前占位。
无锁状态的真实含义
新创建的对象默认处于无锁状态,对象头(Mark Word)里存的是哈希码、分代年龄等基础信息,标志位为01。此时没有任何线程持有锁,也没有任何同步开销——但这个状态只是起点,不是稳定态。
- 它不表示“永远不加锁”,只表示“当前没人要锁”
- 只要第一次有线程执行synchronized代码块,JVM就会立即触发状态判断和可能的转变
- 注意:JDK 1.6+ 默认开启偏向锁,但启动后前4秒内偏向锁被延迟启用(可通过
-XX:BiasedLockingStartupDelay=0关闭)
偏向锁不是加锁,是“记名式占位”
当第一个线程T1首次进入synchronized块时,JVM检查对象头是否可偏向(标志位为01且未被锁定),然后通过一次CAS操作,把T1的线程ID写入Mark Word,并将锁状态维持在01(仍是同一标志位,但语义已变)。这步操作极轻——没有互斥、不进内核、不挂起线程。
- 后续T1再次进入同一同步块:只需比对Mark Word中的线程ID是否为自己,匹配就直接执行,零同步成本
- 如果对象刚创建就立刻被synchronized,且未过偏向延迟期,它会跳过“纯无锁”阶段,直接尝试建立偏向锁
- 若此时已有多个线程同时争抢,JVM会绕过偏向锁,直接走轻量级锁流程(即“跳升”)
为什么需要这一步?核心是省掉90%的无效开销
大量业务对象的生命周期中,其synchronized块几乎总是由同一个线程反复调用(比如单例工具类、线程局部缓存操作)。若每次都要走轻量级锁的CAS流程,哪怕成功,也多了一次原子指令;而偏向锁把“确认归属”这件事压缩成一次CPU寄存器比对。
- 偏向锁初始化仅需1次CAS;轻量级锁每次加锁/解锁都至少1次CAS
- 它解决的是“无竞争但高频访问”的典型模式,不是为高并发设计
- 撤销偏向锁代价较高(需等待安全点、暂停目标线程),所以JVM宁可延迟启用,也不愿频繁撤销










