提示
年轻人不讲理论
锁升级
无锁 → 偏向锁 → 轻量级锁 → 重量级锁
伪代码
//伪代码
class A{
synchronize hello(){
hi();
}
synchronize hi(){
sout("hi")
}
main(){
A a = new A();
new Thread( a.hello(), "1线程").start;
new Thread( a.hello(), "2线程").start;
new Thread( a.hello(), "3线程").start;
new Thread( a.hello(), "4线程").start;
}
}
锁升级过程
最复杂情况下:
-
1线程调用a对象hello方法,需要锁住a对象,查看a对象头存储的锁状态为无锁,将锁状态改为偏向锁,a对象头中设置正在运行的线程id为1线程的id
-
1线程调用hi方法,需要锁住a对象,查看对象头锁状态为偏向锁,拥有锁的线程id和自己线程id一致,不需要抢夺锁
-
1线程调用未结束
-
2线程调用a对象hello方法,需要锁住a对象,查看a对象头存储的锁状态为偏向锁,将锁状态改为轻量级锁,2线程做CAS自旋,循环获取锁
-
3线程调用a对象hello方法,需要锁住a对象,查看a对象头存储的锁状态为轻量级锁,3线程直接做CAS自旋,循环获取锁
-
2,3线程循环时间达到阈值,或者多个线程都在此自旋(自旋浪费cpu),将a对象头中的锁状态改为重量级锁
-
2,3线程查看a对象头锁状态为重量级锁,直接将线程放入a对象头中的线程等待队列,不再自旋
-
4线程调用a对象hello方法,需要锁住a对象,查看a对象头存储的锁状态为重量级锁,直接进入等待队列
-
1线程调用hi结束
-
1线程调用hello结束
-
1线程唤醒其它等待线程
-
等待线程抢夺锁