Java锁升级的实现过程

 更新时间:2020年05月17日 11:43:36   作者:zycxnanwang  
这篇文章主要介绍了Java锁升级的实现过程,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧

对象内存布局

Java对象在内存中存储的布局可以分为3块区域: 对象头、实例数据、对齐填充。

对象头,分为两个部分,第一个部分存储对象自身的运行时数据,又称为Mark Word,32位虚拟机占32bit,64位虚拟机占64bit。如图所示,不同锁状态下,Mark Word的结构,理解下面要介绍的各种锁,和锁升级过程,都需要先充分了解Mark Word的结构。

第二部分是类型指针,指向类元数据指针,虚拟机通过此指针,确定该对象属于那个类的实例。

轻量级锁

轻量级锁是相对于重量级锁(Synchrnoized)而言的,本意是在没有多线程竞争的前提下,减少传统的重量级锁使用操作系统互斥量产生的性能消耗。

轻量级锁的获取

线程进入同步块时,如果此同步对象没有被锁定(即锁标志位为01,是否为偏向锁为0),虚拟机在当前线程的栈帧中建立一个名为锁记录(Lock Record)的空间,用于存储锁对象目前的一个Mark Word的copy

然后虚拟机使用CAS操作,尝试将Mark World更新为指向Lock Record的指针,如果更新成功,那么线程拥有了该对象的锁,并且将锁标志位置位00,如图所示

一旦有两条以上的线程抢占该锁,轻量级锁会升级为重量级锁。锁标志位置为10,Mark Word存储的就是指向重量级锁的指针

轻量级锁释

  • 放如果对象的Mark Word仍然指向着线程的锁记录, 那就用CAS操作把对象当前的Mark Word和线程中复制的Displaced Mark Word替换回来, 如果替换成功, 整个同步过程就完成了。
  • 如果替换失败, 说明有其他线程尝试过获取该锁,轻量级锁膨胀为重量级锁,那就要在释放锁的同时, 唤醒被挂起的线程。

偏向锁

引入偏向锁的目的是在没有多线程竞争的前提下,进一步减少线程同步的性能消耗。

偏向锁的获取

开启偏向锁模式后,锁第一次被线程获取的时候,虚拟机会把对象头中是否为偏向锁的标志位设位0,同时使用CAS操作把获取到这个锁的线程的ID记录在对象的Mark Word之中。

当有另外一个线程去尝试获取这个锁时, 偏向模式就宣告结束。 根据锁对象目前是否处于被锁定的状态, 撤销偏向( Revoke Bias) 后恢复到未锁定( 标志位为“01”)或轻量级锁定( 标志位为“00”) 的状态

偏向锁的释放

偏向锁,并没有显式的锁释放过程,主要依靠锁的批量再偏向(Bulk Rebias)机制实现锁释放。

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

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

整个锁升级过程

参考文章

偏向锁,轻量级锁与重量级锁的区别与膨胀

Java中的偏向锁,轻量级锁, 重量级锁解析

到此这篇关于Java锁升级的实现过程的文章就介绍到这了,更多相关Java锁升级内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • Java出现中文乱码问题分析及解决方案

    Java出现中文乱码问题分析及解决方案

    在Java开发中,处理中文乱码是一个常见的问题,由于字符集和编码的复杂性,开发者可能面临各种导致乱码的情况,正确地处理中文字符集对于确保应用程序的可靠性和国际化至关重要,本文给大家介绍了Java中文乱码分析及解决方案,需要的朋友可以参考下
    2024-02-02
  • mybatis 忽略实体对象的某个属性(2种方式)

    mybatis 忽略实体对象的某个属性(2种方式)

    这篇文章主要介绍了mybatis 忽略实体对象的某个属性方式,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2021-06-06
  • java如何将控制台输出日志写入到指定文件中

    java如何将控制台输出日志写入到指定文件中

    这篇文章主要介绍了java如何将控制台输出日志写入到指定文件中问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2024-04-04
  • Java同步代码块解决银行取钱的安全问题实例分析

    Java同步代码块解决银行取钱的安全问题实例分析

    这篇文章主要介绍了Java同步代码块解决银行取钱的安全问题,结合实例形式分析了java基于线程的同步问题实现与使用相关操作技巧,需要的朋友可以参考下
    2019-08-08
  • Java中获取时间戳的三种方式对比实现

    Java中获取时间戳的三种方式对比实现

    这篇文章主要介绍了Java中获取时间戳的三种方式对比实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2021-01-01
  • SpringCloud 微服务最佳开发实践

    SpringCloud 微服务最佳开发实践

    本文结合我们实际的开发中遇到的一些问题整理出了一份微服务开发的实践规范,对SpringCloud 微服务开发实践相关知识感兴趣的朋友一起看看吧
    2021-07-07
  • SpringCloud Gateway的基本入门和注意点详解

    SpringCloud Gateway的基本入门和注意点详解

    这篇文章主要介绍了SpringCloud Gateway的基本入门和注意点,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2021-10-10
  • 从架构思维角度分析高并发下幂等性解决方案

    从架构思维角度分析高并发下幂等性解决方案

    幂等(idempotent、idempotence)是一个数学与计算机学概念,常见于抽象代数中。 在编程中.一个幂等操作的特点是其任意多次执行所产生的影响均与一次执行的影响相同。幂等函数,或幂等方法,是指可以使用相同参数重复执行,并能获得相同结果的函数
    2022-01-01
  • Mybatis多线程下如何使用Example详解

    Mybatis多线程下如何使用Example详解

    这篇文章主要给大家介绍了关于Mybatis多线程下如何使用Example的相关资料,文中通过示例代码介绍的非常详细,对大家学习或者使用Mybatis具有一定的参考学习价值,需要的朋友们下面来一起学习学习吧
    2019-12-12
  • mybatisPlus实现倒序拼接字符串

    mybatisPlus实现倒序拼接字符串

    这篇文章主要介绍了mybatisPlus实现倒序拼接字符串方式,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-01-01

最新评论