java synchronized 底层实现原理

synchronized的使用分为两种
1.同步代码块

synchronized(object){
     
}

2.同步方法

public synchronized void xxxx(){

}

在此之前需要了解java对象在jvm中 会包含对象头,实例数据,填充数据:
填充数据:由于虚拟机要求对象的起始地址必须是8字节的整数倍,所以填充数据并非必须,仅仅是为对齐字节

实例数据:存放一些类的属性信息,比如父类信息

对象头:是由Mark Word 和 Class Metadata Address 组成
mark word :对象的hashcode,锁信息,年龄代,GC标志等一些信息
Class Metadata Address :指向对象的类元数据,JVM通过这个指针确定该对象是哪个类的实例

所以每个对象都通过对象头里的锁信息关联一个monitor对象


synchronized在jvm中是基于进入和退出monitor(管程)实现的,并且分为显式(通过monitorenter和monitorexit指令来进入或退出monitor)和隐式两种

同步代码块在jvm中的实现(显式)
在hotspot虚拟机中 monitor是由objectmonitor实现的,它包含两个队列 entrylist,waitset,当多个线程同时进入同步代码块时,首先会进入entrylist,当某一个线程获取到锁时,monitor的owner变量便会指向该线程,同时计数器+1表示当前被该线程所获取,当线程执行完毕,或调用wait方法时,owner变量被置null,计数器-1 ,若调用的是wait方法,则线程会进入waitlist队列,等待唤醒

同步方法在jvm中的实现(隐式)
同步方法没有明确的monitorenter,或 monitorexit 指令,而是通过,方法常量池中方法结构表的 ACC_SYNCHRONIED来标识。因此,一个同步方法会被打上ACC_SYNCHRONIZED的表示,并且通过进入方法获取锁,通过异常退出或方法返回来释放锁


后续更通过字节码的形式来讲解monitor,与java 对synchronized的优化(无锁,轻量锁,偏向锁,重量级锁)

你可能感兴趣的:(java synchronized 底层实现原理)