Synchronize的实现原理
Java对象在JVM中的结构如下:
java对象包括:
对象都在32/64位机器中每个部分分别是32/64位,Class Pointer在64位机器默认开启指针压缩,只占用32位。
对象加锁使用的是Mark Word字段,如下是32位的Mark Word
通过 synchronize 关键字给对象加锁的过程如下:
JVM引入偏向锁是为了在无多线程竞争的情况下尽量减少不必要的轻量级锁执行路径,因为轻量级锁的获取及释放依赖多次CAS原子指令,而偏向锁只需要在置换 ThreadID 的时候依赖一次CAS原子指令( 一旦出现多线程竞争的情况就必须撤销偏向锁 )。
偏向锁只有遇到其他线程尝试竞争偏向锁时,持有偏向锁的线程才会释放锁,线程不会主动去释放偏向锁 。偏向锁的撤销,需要等待全局安全点(在这个时间点上没有字节码正在执行),它会首先暂停拥有偏向锁的线程,判断锁对象是否处于被锁定状态,撤销偏向锁后恢复到未锁定(标志位为“01”)或轻量级锁(标志位为“00”)的状态。
轻量级锁所适应的场景是线程交替执行同步块的情况,如果存在同一时间访问同一锁的情况,就会导致轻量级锁膨胀为重量级锁。
synchronize的实现过程:
注意 :lock前缀指令的功能:Synchronize, volatile,CMS都是使用这个实现
当锁膨胀成重量级锁的时候,在JVM中当前锁对象关联的ObjectMonitor对象。
ObjectMonitor对象的数据结构如下:
EntryList是一个后进先出的双向链表,AQS(ReentrantLock)是一个先进先出的双向链表。
ObjectMoniter的流程:
注意:
Synchronize只有一个WaitSet,AQS可以创建多个Condition队列(功能和Waitset类似)。
synchronize的实现原理_技术流水-CSDN博客_synchronize