偏向锁标志位置1
对象头中的标志位默认为“01”,即偏向模式
使用 CAS 操作 让锁对象的对象头的 偏向线程 id 指向当前线程 id
偏向锁的释放只有有竞争时才会释放锁。释放锁只能发生在全局安全点(这个时间点是上没有正在执行的代码)
暂停拥有偏向锁的线程,判断锁对象是否处于被锁定状态
撤销偏向锁,恢复到无锁或轻量级锁的状态
当 锁对象的对象头的 偏向线程 id 指向当前线程 id时,直接执行同步块的代码
当另一个线程获取锁时发现偏向线程 id和自己不一样,需要再测试一下Mark Word中偏向锁的标识是否设置成1(是否还是偏向锁)
如果没有设置,则使用CAS竞争锁;如果设置了,则尝试使用CAS将对象头的偏向锁指向当前线程
CAS 设置失败则膨胀为轻量级锁
获取偏向锁失败后,尝试升级为轻量级锁
当前线程内部创建锁记录(Lock Record)将 markwork 内容记录下来,将Object reference 指向对象
使用 CAS 操作 将锁对象的对象头的 markwork 的内容替换为锁记录的地址和状态00(表示轻量级锁)
记录锁状态为轻量级锁 00
当线程退出同步代码块时
参照锁记录表,删除最新的记录,
当记录中的markwork部分不为 null 时,将保存在锁记录中的markwork 的内容替换到对象头中
再次增加一个锁记录(Lock Record),新的锁记录markwork部分为 null
首先进行自旋,自旋一定次数后(默认10次)还无法获得锁,则膨胀为重量级锁
JDK 1.7 之后,引入了适应性自旋,这次自旋获取到锁了,自旋的次数就会增加;这次自旋没拿到锁,自旋的次数就会减少
无法获得轻量级锁时,膨胀为重量级锁,重量级锁是依赖对象内部的monitor锁来实现的,而monitor又依赖操作系统的MutexLock(互斥锁)来实现的
锁标志位置为10
创建一个ObjectMonitor对象
在锁对象的markword中记录下ObjectMonitor的指针
monitor的 _owner
指向当前线程
monitor计数器+1
将monitor计数器-1
当monitor计数器为0则monitor中_owner
变量就会清空
同事唤醒等待中的其他线程,让他们竞争锁
monitor计数器+1
如果monitor计数器不为0则加入到等待队列,等到持有所得线程释放锁后被唤醒进行竞争
https://www.likecs.com/show-205297476.html
https://www.jianshu.com/p/d53bf830fa09
kxmguyv-1656175183618)]
https://www.likecs.com/show-205297476.html
https://www.jianshu.com/p/d53bf830fa09
https://blog.csdn.net/qq_38826019/article/details/119307386