JVM锁升级的过程
当一个Java类实例对象(obj)被 synchronized(obj){...}包装成为同步监视器对象(即锁对象)时,在不同程度的线程竞争情况下,它对象头(Header)中的Mark Word部分的变化情况如下表所示(即JVM锁升级的过程):
针对线程竞争场景
|
锁状态 |
25bit |
4bit |
1bit |
2bit |
|
23bit |
2bit |
是否偏向锁 |
锁标志位 |
|||
没有线程申请锁的时候 |
无锁 |
对象的HashCode |
分代年龄 |
0 |
01 |
|
只有一个线程申请锁的时候 |
偏向锁 |
线程ID |
Epoch |
分代年龄 |
1 |
01 |
两个线程并发申请锁的时候,此时线程CAS自旋获取锁 |
轻量级锁 |
指向栈中锁记录的指针 |
00 |
|||
超过两个线程申请锁或CAS自旋超过特定次数时,未拿到锁的线程阻塞 |
重量级锁 |
指向重量级锁的指针 |
10 |
|||
GC Roots 不可达的时候 |
GC标记 |
空 |
11 |
备注:锁是不可以降级的!