JUC:10.线程、monitor管程、锁对象之间在synchronized加锁的流程(未完)

一、monitor管程工作原理:

首先,synchronized是一个对象锁,当线程运行到某个临界区,这个临界区使用synchronized对对象obj进行了上锁,此时底层发生了什么?

1.当synchronized对obj上锁后,synchronized会与操作系统层面的monitor管程建立连接,也就是在obj的header中构建一个指向monitor的指针。

2.此时线程访问临界区代码,发现Obj锁,所以去查看obj的header中的mark word中指向管程monitor的指针,从而找到monitor。线程会去查看monitor中的owner部分,访问owner,如果owner目前没有线程访问,该线程成为owner去执行临界区代码段。如果存在owner,线程就被放进monitor中的entryset中,相当于等待队列,等待执行完临界区代码段的线程的唤醒。

二、其中线程与obj的交互如下:

线程访问临界区后,会在栈帧中创建obj的指针以及lock record。

lockrecord中记录着 当前锁记录的地址。

然后会与obj进行交互,尝试使用cas将 lock record中的地址+锁状态 与 obj中的mark word交换。

如果交换成功,mark word 中存储的lock状态就会从00转换为01,表示当前的obj为轻量级锁。

现在的lock record中存放着obj 的 地址, 而 obj中也有到线程锁记录的地址。

完整流程:

首先需要明确,轻量级锁不需要访问monitor,因为与操作系统层面的monitor管程建立连接的花销很高。

在线程之间没有因为临界区而交互时,此时挂载的是轻量级锁。流程如下:

首先线程调用任何方法都会将该方法存放在方法区中,并且在线程的栈帧中保存该方法的局部变量、方法参数以及返回地址。

由于该方法有临界区(加锁),此时在线程的栈帧中还会维护锁对象(synchronized是一个对象锁,锁住的对象需要创建对应的索引信息)的地址以及lock record(锁记录)用于存储当前线程的地址。

同时会在栈帧中的额外槽位slot中维护锁对象的header中的mark word(用于释放锁的还原)。

执行CAS 操作:构造一个新的 Mark Word:

  • 低两位改为 01(轻量级锁标志)

  • 高位填入指向自己栈帧 Lock Record 的地址
    然后对对象头做原子 CAS:

  • 成功 → 轻量级锁加锁成功,对象头和 Lock Record 双向链上了;

  • 失败 → 表示有另一个线程同时在抢这个锁,进入自旋重试或锁膨胀(升级到重量级锁)。

解锁的过程只需要再将栈帧中维护的旧对象头替换回对象中即可。

当有其他线程发现锁对象的锁状态不为00,此时就会进行后续处理,比如自旋,自旋失败后,将后续的锁升级为重量级锁。

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值