开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第20天,点击查看活动详情
1.轻量级锁升级为重量级锁流程图
2.流程图讲解
首先线程1访问同步代码块,此时还是无锁状态,所以给MarkWord中记录的是hashCode等信息。线程1使用CAS修改MarkWord,成功后这个锁成为轻量级锁,线程1分配空间并复制MarkWord到栈帧中的LockRrecord中,并且MarkWord记录的是指向LockRecord中的指针。开始执行同步代码块中的内容。
此时线程2也进来,跟线程1做同样的事情,访问同步代码块,此时还是无锁状态,所以给MarkWord中记录的是hashCode等信息。线程2使用CAS修改MarkWord,结果是失败的,因为MarkWord已经被线程1CAS修改了。此时线程2进行自旋去尝试获取锁,最终还是发现失败,这时,线程2就干了一件事儿,就是弄了一个临时的重量级锁指针。
此时线程1执行完同步代码块后,想CAS替换回LockRecord中记录的信息到MarkWord。发现失败了,因为这个时候,线程2已经把MarkWord中的信息修改为临时的重量级锁指针。此时进入到释放锁并唤醒等待线程。
轻量级锁---重量级锁: 释放锁(前四步)并唤醒等待线程
-
线程1 初始化monitor 对象;
-
将状态设置为膨胀中(inflating);
-
将monitor里边的header属性,set称为对象的markword;(将自己lock record里边的存放的mark word的hashcode,分代年龄,是否为偏向锁 set 到 objectmonitor对象的header属性里)
-
设置对象头为重量级锁状态(标记为改为00);然后将前30位指向第1步他初始化的monitor 对象;(真正的锁升级是由线程1操控的)
-
唤醒线程2;
线程2 开始争抢重量级锁。(线程2就干了一件事儿,就是弄了一个临时的重量级锁指针吧?还不是最后的重量级锁指针。因为最后的重量级锁指针是线程1初始化的并且是线程1修改的。 而且,线程2被唤醒之后,还不一定能够抢到这个重量级锁。Sync是非公平锁。 线程2费力不讨好,但是线程2做了一件伟大的事情:他是锁升级的奠基者。)