偏向锁、轻量级锁、重量级锁解析

Java 对象头

在32位虚拟机和64位虚拟机的 Mark Word 所占用的字节大小不一样,32位虚拟机的 Mark Word 和 class Pointer 分别占用 32bits 的字节,而 64位虚拟机的 Mark Word 和 class Pointer 占用了64bits 的字节,下面我们以 32位虚拟机为例,来看一下其 Mark Word 的字节具体是如何分配的

32位虚拟机

在这里插入图片描述
在这里插入图片描述

64位虚拟机

在这里插入图片描述

偏向锁、轻量级锁的状态转化及对象Mark Word的关系

偏向锁、轻量级锁的状态转化及对象Mark Word的关系

偏向锁的获得和撤销流程

时序图

偏向锁的获得和撤销流程

流程图

在这里插入图片描述

轻量级锁及膨胀流程

时序图

轻量级锁及膨胀流程

轻量级锁获取流程图

在这里插入图片描述

重量级锁获取流程图

重量级锁获取流程图

偏向锁的批量再偏向(Bulk Rebias)机制

偏向锁这个机制很特殊, 别的锁在执行完同步代码块后, 都会有释放锁的操作, 而偏向锁并没有直观意义上的“释放锁”操作。

那么作为开发人员, 很自然会产生的一个问题就是, 如果一个对象先偏向于某个线程, 执行完同步代码后, 另一个线程就不能直接重新获得偏向锁吗? 答案是可以, JVM 提供了批量再偏向机制(Bulk Rebias)机制

该机制的主要工作原理如下:

  • 引入一个概念 epoch, 其本质是一个时间戳 , 代表了偏向锁的有效性
  • 从前文描述的对象头结构中可以看到, epoch 存储在可偏向对象的 MarkWord 中。
  • 除了对象中的 epoch, 对象所属的类 class 信息中, 也会保存一个 epoch 值
  • 每当遇到一个全局安全点时, 如果要对 class C 进行批量再偏向, 则首先对 class C 中保存的 epoch 进行增加操作, 得到一个新的 epoch_new
  • 然后扫描所有持有 class C 实例的线程栈, 根据线程栈的信息判断出该线程是否锁定了该对象, 仅将 epoch_new 的值赋给被锁定的对象中。
  • 退出安全点后, 当有线程需要尝试获取偏向锁时, 直接检查 class C 中存储的 epoch 值是否与目标对象中存储的 epoch 值相等, 如果不相等, 则说明该对象的偏向锁已经无效了, 可以尝试对此对象重新进行偏向操作。

以class为单位,为每个class维护一个偏向锁撤销计数器。每一次该class的对象发生偏向撤销操作是,该计数器+1,当这个值达到重偏向阈值(默认20)时,JVM就认为该class的偏向锁有问题,因此会进行批量重偏向。每个class对象也会有一个对应的epoch字段,每个处于偏向锁状态对象的mark word中也有该字段,其初始值为创建该对象时,class中的epoch值。每次发生批量重偏向时,就将该值+1,同时遍历JVM中所有线程的站,找到该class所有正处于加锁状态的偏向锁,将其epoch字段改为新值。下次获取锁时,发现当前对象的epoch值和class不相等,那就算当前已经偏向了其他线程,也不会执行撤销操作,而是直接通过CAS操作将其mark word的Thread Id改为当前线程ID。

批量撤销:当某个类的对象的偏向锁累计被撤销到阈值40次(从40次开始),则偏向锁认为偏向锁撤销过于频繁,则后面的对象包括新生成的对象(标识为101和001)如果需要使用锁,则直接轻量级锁,不在使用偏向锁(即禁用了偏向锁)。

参考

线程安全与锁优化
https://blog.csdn.net/lengxiao1993/article/details/81568130
https://www.zhihu.com/question/55075763
https://mp.weixin.qq.com/s/RGhSIbQpKn7V1YG7rIVTSw

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值