实现synchronized的基础: Java对象头 + Monitor

对象头的结构如下:

虚拟机位数 头对象结构 说明
32/64bit Mark Word 默认存储对象的hashcode,分代年龄,锁类型,锁标志位等信息。
32/64bit Class Metadata Address 类型指针指向对象的类元数据,JVM通过这个指针确定该对象是哪个类的数据。

Mark Word的说明图:

synchronized和reentrantLock的底层实现

 

而对于Monitor,每个Java对象天生自带一把看不见的锁(内部锁/Monitor锁)。

Monitor锁的竞争与释放如下图所示:

synchronized和reentrantLock的底层实现

 

在早期的Java版本中,synchronized属于重量级锁,依赖于Mutex Lock实现。线程之间的切换需要从用户态置换到核心态,开销很大。在 Java 6之后,synchronized性能得到了很大提升。引入了四级锁结构,无锁->偏向锁->轻量级锁->重量级锁。

 

ReentrantLock的实现基于著名的AQS。当多个线程调用同一个ReentrantLock对象的lock()方法时,大致原理是每个线程都尝试去修改锁对象内一个状态属性state(继承自AbstractQueuedSynchronizer)的值,这个修改过程采用了CAS(compare and swap)技术即每个线程都想把这个变量从数据0改变成1. 如果一个线程修改成功则成为锁对象的owner,否则 LockSupport.park中止该线程,并调用该线程的interrupt方法设置线程的interrupted状态,并创建一个node存放该线程并将node加入链表中。当某线程a 调用unlock方法时,从链表中取出a线程对应node的next节点并调用LockSupport.unpark给对应线程一个许可让其继续执行。(以非公平锁为例)

 

ReentrantLock和synchronized的可重入性实现: https://www.jianshu.com/p/ca7df6c1110f

相关文章:

  • 2021-11-03
  • 2021-12-31
  • 2021-10-23
  • 2022-01-19
  • 2021-08-19
  • 2021-07-15
  • 2022-02-22
猜你喜欢
  • 2021-07-08
  • 2022-12-23
  • 2022-12-23
  • 2021-05-30
  • 2021-05-14
  • 2021-06-07
相关资源
相似解决方案