java锁升级简述
锁升级过程:
锁对象为o,线程a 在执行,线程b也来获取锁那么就会造成锁升级
1 偏向锁->轻量级锁:
会触发safepoint全局安全点,就是暂停所有线程的运行。在安全点之内,会在线程a的栈帧中创建一个所记录,所记录指向锁对象o,将o的markword复制到所记录中,然后将锁对象o的markword设置为轻量级锁状态,也就是最后两位为:00。
思考:为什么偏向锁需要safepoint?
解答:正是由于其偏向的特性,所以使得线程a在锁代码块在执行完后也不会更改锁对象o的markword,那么所有的线程都不知到是否解锁了,又担心在不使用安全点的情况下进行偏向锁撤销的过程中,线程a已经执行完了锁代码,导致锁记录在a不执行同步代码块的时候却依旧持有锁的情况发生。所以会使用safepoint暂停线程,所以,偏向锁的撤销是性能极差的,于是在jdk15之后就将此默认关闭了。
2 轻量级锁->重量级锁
safepoint安全点过后,b用cas发现锁对象的对象头为00并且指向另一个线程的锁记录,那么自旋失败,这时候b就会自旋几次,但是都失败,就会为a申请monitor重量级锁,让a的markword指向monitor,owner设置为a,将自己放到monitor的entrylist中等待。
3 解锁
等到a执行完后,用cas解锁,结果失败,就去执行重量级锁解锁逻辑,将monitor的owner设置为null,并且唤醒entrylist中的线程。