synchronized锁是如何升级的

1 锁升级过程

synchronized锁升过程:偏向锁-》轻量级锁-》重量级锁。
在这里插入图片描述

图1 synchronized锁升级过程

2 锁升级流程

synchronized锁升级的具体流程如图2所示。
在这里插入图片描述

图2 synchronized锁升级流程

2.1 偏向锁->轻量级锁

线程A请求synchronized对象,比较同步块对象存储的线程S ID与线程A ID是否相同,如果相同,那么执行同步块,无需使用CAS加锁或解锁;如果不同,那么检查synchronized对象中记录的线程S是否存活,如果线程S未存活,那么synchronized对象被重置为无锁状态,线程A通过竞争将其设置为偏向锁,此时,synchronized对象头中存储线程A的ID,如果线程S存活,那么查找线程S的栈帧信息,如果线程S仍要继续持有该synchronized对象,那么暂停线程S,撤销偏向锁,升级为轻量级锁,如果线程S不再使用该synchronized对象,将synchronized对象设为无锁状态,重新偏向线程A。

2.2 轻量级锁->重量级锁

线程A获取轻量级锁时先将synchronized对象头Mark Word复制一份到线程A在栈帧中创建的存储锁记录空间(即DispalcedMarkWord),然后使用CAS将对象头中的内容替换为线程A存储的所记录(DisplacedMarkWord)地址。如果线程A复制对象头时,线程B也准备获取锁,复制对象头到线程B的锁记录空间,当线程B进行CAS时发现,线程A已经将对象头替换,线程B的CAS失败,线程B尝试使用自旋等待线程A释放锁。如果线程B自旋次数到了上限,线程A仍没有释放锁,线程B仍在自选等待,此时,线程C又来竞争锁对象,轻量级锁会膨胀为重量级锁。重量级锁将未获得锁的线程阻塞不消耗CPU,防止CPU空运行。

3 锁信息存储位置

锁:为对象加锁,因此,锁信息存储在对象中,而对象中是在哪里存储呢?
首先了解:对象结构https://blog.csdn.net/Xin_101/article/details/117568632
锁信息存储在对象头MarkWord中。

3.1 无锁

锁状态25位31位1位4位1位(偏向锁位)2位(锁标志)
无锁unusedhashCode(调用hashCode方法时填充)unused分代年龄001

3.2 偏向锁

锁状态54位2位1位4位1位(偏向锁位)2位(锁标志)
偏向锁当前线程指针Epochunused分代年龄101

3.3 轻量级锁(自旋锁)

锁状态62位2位(锁标志)
轻量级锁指向线程栈中LockRecord的指针(通过自旋竞争锁CAS,有次数上限)00

JDK1.6前:默认10次自旋,-XX:PreBlockSpin配置,或者超过CPU核数的一半,自动升级重量级锁 。
JDK1.6之后,自适应自旋(Adaptive Self Spinning),JVM自动调整。

3.4 重量级锁

向操纵系统申请资源:Linux mutex,多个线程竞争资源,线程挂起后,进入等待队列,等待操作系统调度。

锁状态62位2位(锁标志)
重量级锁指向互斥量(重量级锁)的指针10

4 小结

序号优点缺点应用场景
1偏向锁避免CAS,无需加锁或解锁,和非同步方法时间相差纳秒级别竞争的线程较多时,会带来额外的锁撤销消耗基本没有线程竞争的同步场景
2轻量级锁竞争的线程不会阻塞,使用自旋,提高程序响应速度长时间自旋,CPU消耗较多少量线程竞争锁对象,并且线程持久锁时间不长,追求响应速度的场景
3重量级锁竞争的线程阻塞,不会导致CPU空运行,节约CPU资源线程阻塞,响应时间长很多线程竞争锁,并且锁持有时间较长,追求吞吐量的场景

Q&A

为什么要使用重量级锁

因为轻量级锁(自旋锁CAS)在自旋等待时会占用CPU资源,竞争的锁(线程)越多,CPU消耗越大,容易导致CPU过载。

为什么使用偏向锁或轻量级锁

效率高。


【参考文献】
[1]http://blog.sina.com.cn/s/blog_c038e9930102v2hs.html
[2]https://blog.csdn.net/qq_24434251/article/details/114435631
[3]https://blog.csdn.net/weixin_42213903/article/details/97044043
[4]https://blog.csdn.net/zzti_erlie/article/details/103997713

  • 4
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

天然玩家

坚持才能做到极致

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值