[并发] Synchronized锁升级总结

[并发] Synchronized锁升级总结

线程进入时候检测标志位

  • 如果是10则是重量级锁,
  • 如果是00则是轻量级锁,
  • 如果是01则是标志位:继续判断:

​ (1)判断是否是偏向锁

​ + 如果是的话,检测Mark Word对象头中是否是当前线程;是的话,执行业务逻辑,该线程的每次进入同步代码块,不会发生额外的性能消耗。(只要不发生线程间竞争,就一直偏向该线程)

​ + 如果不是的话就CAS操作获取偏向锁,主要是把标志位置为1,记录偏向锁的线程ID;

​ ++ 如果偏向锁的获取CAS操作成功,就替换对象头中的偏向ID为当前线程。

​ ++ 如果偏向锁的获取CAS操作失败,则说明有线程竞争,撤销偏向锁(撤销需要到达安全点撤销),升级偏向锁为轻量级锁。

​ +++ 升级为轻量级锁的话,检查持有偏向锁的线程状态,如果该线程已经退出同步代码块或者是未活动状态,直接释放锁,把标志位置为01

​ +++ 升级为轻量级锁的话,检查持有偏向锁的线程状态,如果未退出同步代码块或者是活动状态会在把持有偏向锁的线程的栈帧中创建一块锁空间(Lock reward),拷贝Mark Word中到其锁记录中,然后把该指针CAS操作指向锁对象中(这里是双向都指)。如果cas操作成功,即成功升级为轻量级锁,如果cas失败,查看锁空间中是否已经有指针指向了锁对象,指向了也是升级为了轻量级锁。(标志位换为00)

​ ++++ 成功获取到轻量级锁,开始执行同步代码块,最终释放轻量级锁(释放过程:通过cas操作,看是否指向对象头的指针还存在,看拷贝到栈空间中的markword和对象头中是否一致,一致就释放成功。)

​ ++++ 未成功获取到轻量级锁,再继续自旋cas获取(引入了自适应自旋)

​ +++++ 如果自旋一直没能获取到轻量级锁,超过一定的限度,就升级为重量级锁。转换为重量级锁,该锁会对应一个monitor对象,底层通过monitorenter和monitorexit指令来保证。挂起当前线程。

原文地址:https://www.cnblogs.com/jiyongjia/p/13387716.html