Synchronized、ReentrantLock 和 ReadWriteLock底层原理

2023-12-28 13:42:06

Synchronized 底层原理

1. JVM 层面的实现

? synchronized 是 Java 中的一个关键字,它提供了一种简单的策略来实现线程同步。在 JVM 层面,synchronized 可以依赖于对象内部的监视器锁(monitor lock)来实现同步。

  • 锁的获取与释放:当一个线程进入?synchronized?修饰的方法或代码块时,它会自动获取锁,退出时自动释放锁。
  • 对象头:Java 对象头中有一部分是用来实现锁的功能,称为 Mark Word。在运行时,Mark Word 中的信息会被用来存储锁的状态或者指向锁记录(Lock Record)的指针。
  • 锁的状态:锁可以处于无锁状态、偏向锁状态、轻量级锁状态或重量级锁状态。随着竞争的增加,锁可以升级,但不会降级。

2. 锁的升级过程

  • 偏向锁:当没有竞争出现时,默认开启偏向锁,它会偏向于第一个获取它的线程,减少之后的同步操作。
  • 轻量级锁:当有其他线程尝试获取已被偏向的锁时,偏向锁会升级为轻量级锁,此时线程会在对象头上的 Mark Word 中创建锁记录。
  • 重量级锁:当锁处于轻量级状态下,如果有更多线程加入竞争,轻量级锁会膨胀为重量级锁,此时线程会进入阻塞状态,等待操作系统的调度。

ReentrantLock 底层原理

1. Java API 层面的控制

? ReentrantLock 是 Java 中 java.util.concurrent.locks 包下的一个类。它提供了比 synchronized 更丰富的锁操作功能。

  • 显式锁操作:使用?ReentrantLock?时,需要显示地调用?lock()?和?unlock()?方法来获取和释放锁。
  • 可重入性ReentrantLock?支持可重入,即同一个线程可以多次获得同一把锁。

2. AQS(AbstractQueuedSynchronizer)框架

? ReentrantLock 的实现依赖于 AQS,这是一个用于构建锁和其他同步组件的框架。

  • 状态变量:AQS 内部有一个整型的状态变量来表示锁的状态。
  • 节点队列:AQS 使用一个双向链表(称为 CLH 队列)来管理线程的排队工作。
  • 独占模式ReentrantLock?在 AQS 的基础上实现了独占模式,即任何时刻只有一个线程持有锁。

ReadWriteLock 底层原理

1. 分离读写操作

? ReadWriteLock 是一个接口,它的实现类(如 ReentrantReadWriteLock)允许多个线程同时读取,但只有一个线程可以写入。

  • 读锁和写锁ReadWriteLock?提供了两种锁:读锁(共享锁)和写锁(独占锁)。

2. 基于 AQS 实现

? ReentrantReadWriteLock 的实现也是基于 AQS,但是它使用了 AQS 的共享模式。

  • 状态变量的特殊使用:AQS 状态变量的高位表示写锁状态,低位表示读锁的数量。
  • 锁降级:支持写锁降级为读锁,即持有写锁的线程可以获取读锁,然后释放写锁,这在某些情况下可以减少锁竞争。

总结

? SynchronizedReentrantLockReadWriteLock 都是用于实现线程同步的机制,但它们的实现原理和适用场景有所不同。Synchronized 是基于 JVM 实现的内置锁机制,而 ReentrantLockReadWriteLock 是基于 Java API 层面,通过 AQS 框架来实现更复杂的锁操作和同步控制。

文章来源:https://blog.csdn.net/u014745465/article/details/135266493
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。