Java synchronized重量级锁实现过程浅析

 更新时间:2023年02月11日 15:50:25   作者:每天都要进步一点点  
这篇文章主要介绍了Java synchronized重量级锁实现过程,synchronized是Java里的一个关键字,起到的一个效果是"监视器锁",它的功能就是保证操作的原子性,同时禁止指令重排序和保证内存的可见性

一、什么是重量级锁

当有大量的线程都在竞争同一把锁的时候,这个时候加的锁,就是重量级锁。

这个重量级锁其实指的就是JVM内部的ObjectMonitor监视器对象:

ObjectMonitor() {
    _header       = NULL;		//锁对象的原始对象头
    _count        = 0;			//抢占当前锁的线程数量
    _waiters      = 0,			//调用wait方法后等待的线程数量
    _recursions   = 0;			//记录锁重入次数
    _object       = NULL;
    _owner        = NULL;		//指向持有ObjectMonitor的线程
    _WaitSet      = NULL;		//处于wait状态的线程队列,等待被唤醒
    _WaitSetLock  = 0 ;
    _Responsible  = NULL ;
    _succ         = NULL ;
    _cxq          = NULL ;
    FreeNext      = NULL ;
    _EntryList    = NULL ;		//等待锁的线程队列
    _SpinFreq     = 0 ;
    _SpinClock    = 0 ;
    OwnerIsThread = 0 ;
    _previous_owner_tid = 0;
  }

二、重量级锁的演示

public class HightweightLockDemo02 {
    public static void main(String[] args) {
        Object objLock = new Object();
        new Thread(() -> {
            synchronized (objLock) {
                System.out.println(ClassLayout.parseInstance(objLock).toPrintable());
            }
        }, "t1").start();
        new Thread(() -> {
            synchronized (objLock) {
                System.out.println(ClassLayout.parseInstance(objLock).toPrintable());
            }
        }, "t2").start();
    }
}

运行程序:

java.lang.Object object internals:
 OFFSET  SIZE   TYPE DESCRIPTION                               VALUE
      0     4        (object header)                           1a 33 c9 e1 (00011010 00110011 11001001 11100001) (-506907878)
      4     4        (object header)                           43 01 00 00 (01000011 00000001 00000000 00000000) (323)
      8     4        (object header)                           e5 01 00 f8 (11100101 00000001 00000000 11111000) (-134217243)
     12     4        (loss due to the next object alignment)
Instance size: 16 bytes
Space losses: 0 bytes internal + 4 bytes external = 4 bytes total
java.lang.Object object internals:
 OFFSET  SIZE   TYPE DESCRIPTION                               VALUE
      0     4        (object header)                           1a 33 c9 e1 (00011010 00110011 11001001 11100001) (-506907878)
      4     4        (object header)                           43 01 00 00 (01000011 00000001 00000000 00000000) (323)
      8     4        (object header)                           e5 01 00 f8 (11100101 00000001 00000000 11111000) (-134217243)
     12     4        (loss due to the next object alignment)
Instance size: 16 bytes
Space losses: 0 bytes internal + 4 bytes external = 4 bytes total

可见,当多个线程共同抢占同一把锁的时候,锁对象MarkWord的最后三位是“010”,代表的就是一个重量级锁。

三、重量级锁的原理

以上述代码为例,synchronized获取的锁是重量级锁,synchronized修饰代码块,使用javap -p -v .\HightweightLockDemo02.class指令查看其字节码:

在编译的时候,JVM会在同步块开始位置插入monitorenter指令,在同步块结束位置插入monitorexit指令。当线程执行到monitorenter指令时,会尝试获取对象所对应的Monitor所有权,如果获取成功,则表示获取到了锁,会在Monitor的_owner中存在当前线程的ID,这样它将处于锁定状态,除非退出同步块,否则其他线程无法获取得到这个Monitor。

四、锁的优缺点对比

下表是对各种状态的锁的对比:

锁的类型优点缺点适用场景
偏向锁加锁和解锁不需要额外的消耗,和执行非同步方法相比仅存在纳秒级的差距如果线程间存在锁竞争,会带来额外的锁撤销的消耗适用于只有一个线程访问同步块场景
轻量级锁竞争的线程不会阻塞,提高了程序的响应速度如果始终得不到锁竞争的线程,使用自旋会消耗CPU,导致CPU空转追求响应时间 同步块执行速度非常快
重量级锁线程竞争不使用自旋,不会消耗CPU线程阻塞,响应时间缓慢追求吞吐量 同步块执行时间较长

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

相关文章

  • SpringBoot详解如何整合Redis缓存验证码

    SpringBoot详解如何整合Redis缓存验证码

    本文主要介绍了SpringBoot集成Redis实现验证码的缓存简单案例,文中通过示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2022-07-07
  • 详解SpringBoot上传图片到阿里云的OSS对象存储中

    详解SpringBoot上传图片到阿里云的OSS对象存储中

    这篇文章主要介绍了SpringBoot上传图片到阿里云的OSS对象存储中,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2020-10-10
  • 详解SpringBoot 添加对JSP的支持(附常见坑点)

    详解SpringBoot 添加对JSP的支持(附常见坑点)

    这篇文章主要介绍了详解SpringBoot 添加对JSP的支持(附常见坑点),非常具有实用价值,需要的朋友可以参考下
    2017-10-10
  • 浅析Java语言中状态模式的优点

    浅析Java语言中状态模式的优点

    状态模式允许对象在内部状态改变时改变它的行为,对象看起来好像修改了它的类。这个模式将状态封装成独立的类,并将动作委托到 代表当前状态的对象,我们知道行为会随着内部状态而改变
    2023-02-02
  • Spring中@Import的各种用法以及ImportAware接口详解

    Spring中@Import的各种用法以及ImportAware接口详解

    这篇文章主要介绍了Spring中@Import的各种用法以及ImportAware接口详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2019-10-10
  • SpringBoot集成MyBatis的多种方式

    SpringBoot集成MyBatis的多种方式

    本文深入解析了Spring Boot集成MyBatis的多种方式,包括XML配置、注解配置以及MyBatis的动态SQL等,具有一定的参考价值,感兴趣的可以了解一下
    2023-12-12
  • MyBatis查询数据,赋值给List集合时,数据缺少的问题及解决

    MyBatis查询数据,赋值给List集合时,数据缺少的问题及解决

    这篇文章主要介绍了MyBatis查询数据,赋值给List集合时,数据缺少的问题及解决方案,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-01-01
  • Mybatis Generator逆向工程的使用详细教程

    Mybatis Generator逆向工程的使用详细教程

    这篇文章主要介绍了Mybatis Generator逆向工程的使用详细教程,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2020-06-06
  • Java格式化日期和时间三种方法

    Java格式化日期和时间三种方法

    这篇文章主要给大家介绍了关于Java格式化日期和时间三种方法的相关资料,最近遇到很多在Java里获取当前时间的问题,文中通过图文以及实例代码介绍的非常详细,需要的朋友可以参考下
    2023-07-07
  • com.mysql.jdbc.Driver 和 com.mysql.cj.jdbc.Driver的区别及设定serverTimezone的方法

    com.mysql.jdbc.Driver 和 com.mysql.cj.jdbc.Driver的区

    这篇文章主要介绍了com.mysql.jdbc.Driver 和 com.mysql.cj.jdbc.Driver的区别以及设定serverTimezone的方法,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2023-09-09

最新评论