前提条件:
三个线程A 、B、C,一个待锁对象obj
obj头部变化:
对象状态 | Markword | 是否偏向 | 锁状态 |
---|---|---|---|
无锁 | 正常对象头中的Markword | 0 | 01 |
偏向锁 | 偏向线程Id + 其他 | 1 | 01 |
轻量级锁 | 线程栈帧中的Display Markword(对象头复制) | 00 | |
重量级锁 | 重量级锁对象指针 | 10 |
对象锁升级+线程状态
对象:偏向锁(compete num == 1)、轻量级锁(compete num == 2)、重量级锁(compete num > 2)
线程:偏向(thread num == 1)、自旋(thread num == 2)、重量互斥 (thread num > 2)
模拟运行
1)A——>obj A尝试获取对象obj,发现偏向标志位为0,obj利用CAS获取A线程ID存储于对象头中Markword
2)B——>obj B尝试获取对象obj,发现偏向标志位为1,则obj取消偏向A,升级为轻量级A【A首先在本地栈帧中存储一份obj Markword的副本,A通过CAS获取到obj指针,B此时处于自旋状态,obj锁状态变为00且对象头中Markword存储A栈帧中的副本】
3)C——>obj C尝试竞争获取obj,此时竞争线程已超过2,obj则升级到重量级锁,锁状态为10,A获得锁,B 、C处于等待状态
说明
上述锁升级假设每次为A获取obj成功。
锁只能升级,不能降级。
自旋发生在两个线程同时竞争,大于两个则升级为重量级。
锁升级优化版本在jdk1.6