并发编程(二十三)Synchronized锁升级-Markword的转化过程

113 阅读2分钟

开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第21天,点击查看活动详情

1.Markword的转化过程-偏向锁中

创建一个对象,此时对象里边没有hashcode,所以该对象可以使用我们的偏向锁,偏向锁不会考虑hashcode, 他会直接将自己的线程id放到我们的markword里边,不需要考虑后续的替换问题。 所以呢,一旦我们的对象主动调用了Object的hashcode方法,我们的偏向锁就自动不可用了。

2.Markword的转化过程-轻量级锁中

如果我们的对象有了hashcode和分代年龄和是否为偏向锁(30位)。在轻量级锁的状态下,这30位会被复制到我们的轻量级锁线程持有者的栈帧里的lock record里边记录。与此同时,我们的对象的markword里边存放的是我们的指向轻量级锁线程持有者的栈帧的lock recod里。如果一直存在轻量级锁竞争,在未发生锁膨胀的前提下,一直会保持轻量级锁,A线程释放的时候,会将markword替换回对象的markword里边,B线程下次再从新走一遍displace mark word;

3.Markword的转化过程-重量级锁中

一旦发生了轻量级膨胀为重量级锁。前提,A线程持有锁;B线程争抢。 B线程将marikword里边A线程的指针替换成一个临时的(过度的)重量级锁指针,为了让A线程在cas往回替换markword的时候失败。 A线程替换回markword失败后,会发起:

1.初始化monitor对象;

2.将状态设置为膨胀中;

3.将替换失败的 markword放到objectmonitro的head属性里;

4.改变markword的锁标志为10;将markword里的 30 位设置为指向自己第一步初始化的那个monitor对象;

5.唤醒B线程;

6.以后这个对象只能作为重量级锁;

4.总结

这些过程中Markword信息从未丢失。