加锁 后何时解锁_轻量级锁加解锁过程详解

7c492fc711234cc466eea8e97035d0c6.png

从Java SE 1.6开始,为了减少获得锁和释放锁带来的性能消耗,就引入了轻量级锁。轻量级锁在对象内存布局中 MarkWord 锁标志位为 00,它可以由偏向锁对象因存在多个线程访问而升级成轻量级锁,当然,轻量级锁也可能因多个线程同时访问同步代码块升级成重量级锁。

一、加锁过程

加锁过程主要分为3步:

1、在线程执行同步代码块之前,JVM会现在当前线程的栈桢中创建用于存储锁记录的空间,并将锁对象头中的 markWord 信息复制到锁记录中,这个官方称为 Displaced Mard Word。然后线程尝试使用 CAS 将对象头中的 MarkWord 替换为指向锁记录的指针。

c80ee60accc66880e78e40443892f897.png

2、将锁对象头中的 markWord 信息复制到锁记录中,这个官方称为 Displaced Mard Word。然后线程尝试使用 CAS 将对象头中的 MarkWord 替换为指向锁记录的指针。如果替换成功,则进入步骤3,失败则进入步骤4。

3、CAS 替换成功说明当前线程已获得该锁,此时在栈桢中锁标志位信息也更新为轻量级锁状态:00。此时的栈桢与锁对象头的状态如图二所示。

212f2d91596981207fb532d97f92dcbc.png
图二

4、如果CAS 替换失败则说明当前时间锁对象已被某个线程占有,那么此时当前线程只有通过自旋的方式去获取锁。如果在自旋一定次数后仍为获得锁,那么轻量级锁将会升级成重量级锁。

升级成重量级锁带来的变化就是对象头中锁标志位将变为 10(重量级锁),MarkWord 中存储的也就是指向互斥量(重量级锁)的指针。(注意!!!此时,锁对象头的 MarkWord 已经发生了改变)。

轻量级锁升级过程大概流程图如下:

65449e18ed9469e0b0a9bb9dd60017bf.png
图三

2、解锁过程

轻量级锁解锁时,会使用CAS将之前复制在栈桢中的 Displaced Mard Word 替换回 Mark Word 中。如果替换成功,则说明整个过程都成功执行,期间没有其他线程访问同步代码块。

但如果替换失败了,表示当前线程在执行同步代码块期间,有其他线程也在访问,当前锁资源是存在竞争的,那么锁将会膨胀成重量级锁。图三中重量级锁部分也就眼神了锁膨胀的过程。

3、轻量级锁的优缺点

轻量级锁涉及到一个自旋的问题,而自旋操作是会消耗CPU资源的。为了避免无用的自旋,当锁资源存在线程竞争时,偏向锁就会升级为重量级锁来避免其他线程无用的自旋操作。所以这就引出了偏向锁的一个缺点:如果始终无法获得锁资源,线程就会自旋消耗CPU资源。

但是偏向锁相对于重量级锁的一个有点就是:因为线程在竞争资源时采用的是自旋,而不是阻塞,也就避免了线程的切换带来的时间消耗,提高了程序的响应速度。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值