synchronized关键字的底层实现

介绍synchronized关键字的底层之前,先要了解对象在内存中存储的布局。

  • 在Java虚拟机中,对象在内存中存储的布局可以分为三块区域:对象头(Header)、实例数据(Instance Data)、对齐填充(Padding)。
  • 其中对象头包括两部分信息,一部分使用于存储对象自身的运行时数据,如哈希码、GC分代年龄、锁状态标志、线程持有的锁、偏向线程ID、偏向时间戳等。
  • 对象头的另一部分是类型指针,即对象指向它的类元数据的指针虚拟机通过这个指针来确定这个对象是哪个类的实例。

在这里插入图片描述
因此Java识别对象是否存在锁是在虚拟机中通过对象头中的锁标志来判断的,因此从对象头中的指向重量级锁的指针开始认识synchronized的底层实现。

对于synchronized的对象锁,指针是指向的一个monitor对象的起始地址,每一个对象实例都会有一个monitor。monitor是跟随对象创建以及销毁的,同时线程在获取对象锁的时候也可以自动生成。

对于synchronized修饰代码块

根据虚拟机规范要求,在执行monitorenter指令时,首先要尝试获取对象锁,也就是上文我们提到了monitor对象。如果这个对象没有被锁定,或者当前线程已经拥有了这个对象的锁,那么就把锁的计数器(_count)加1。当然与之对应执行monitorexit指令时,锁的计数器(_count)也会减1。

对于synchronized修饰方法

当synchronized修饰方法时,不是通过monitor对象来进行锁的判断的,在修饰方法是通过ACC_SYNCHRONIZED标识,Java虚拟机通过验证ACC_SYNCHRONIZED标识来判断是否是一个需要同步的方法。

以上就对于synchronized关键字的底层理解,该文章中引用了https://baijiahao.baidu.com/s?id=1612142459503895416&wfr=spider&for=pc以及《深入理解Java虚拟机》

发布了55 篇原创文章 · 获赞 6 · 访问量 4013

猜你喜欢

转载自blog.csdn.net/qq_40126996/article/details/100578334