Java 中 ReentrantLock 的底层实现原理是什么?(基于 AQS)

· 约 4 分钟读完 · 第 79 / 274 章

推荐答案

ReentrantLock 的底层实现基于 AbstractQueuedSynchronizer(AQS)。AQS 是一个用于构建锁和同步器的框架,它通过一个 FIFO 队列来管理线程的阻塞和唤醒。ReentrantLock 通过继承 AQS 并实现其抽象方法来实现可重入锁的功能。

本题详细解读

AQS 的核心思想

AQS 的核心思想是通过一个 volatile 的 int 类型的 state 变量来表示同步状态。state 的值可以表示锁的状态,比如 0 表示锁未被占用,1 表示锁被占用。AQS 还维护了一个 FIFO 队列,用于管理等待获取锁的线程。

ReentrantLock 的实现

ReentrantLock 通过继承 AQS 并实现其 tryAcquire 和 tryRelease 方法来实现锁的获取和释放。

1. 获取锁

当线程尝试获取锁时,ReentrantLock 会调用 AQS 的 acquire 方法,该方法会调用 tryAcquire 方法来尝试获取锁。

  • 如果 state 为 0,表示锁未被占用,当前线程通过 CAS 操作将 state 设置为 1,并将当前线程设置为独占锁的持有者。
  • 如果 state 不为 0,且当前线程已经是锁的持有者,则通过增加 state 的值来实现可重入。

2. 释放锁

当线程释放锁时,ReentrantLock 会调用 AQS 的 release 方法,该方法会调用 tryRelease 方法来释放锁。

  • 如果 state 减到 0,表示锁已经完全释放,当前线程不再是锁的持有者。
  • 如果 state 不为 0,表示锁仍然被持有,当前线程仍然是锁的持有者。

公平锁与非公平锁

ReentrantLock 支持公平锁和非公平锁两种模式。公平锁会按照线程请求锁的顺序来分配锁,而非公平锁则允许插队。

  • 公平锁:在 tryAcquire 方法中,会先检查是否有其他线程在等待获取锁,如果有,则当前线程不会尝试获取锁。
  • 非公平锁:在 tryAcquire 方法中,当前线程会直接尝试获取锁,而不考虑是否有其他线程在等待。

总结

ReentrantLock 的底层实现基于 AQS,通过 state 变量和 FIFO 队列来管理锁的状态和线程的阻塞与唤醒。ReentrantLock 支持可重入、公平锁和非公平锁等特性,是一个功能强大的同步工具。