面试鸭 Java 后端面试题, 你真的理解 AQS 原理了吗?
面试鸭 Java 后端面试题, 你真的理解 AQS 原理了吗?
QA
Step 1
Q:: 什么是AQS?
A:: AQS(AbstractQueuedSynchronizer)是一个用于构建锁和同步器的框架,提供了一个基于FIFO(先进先出)等待队列的实现。AQS通过将线程的排队和状态管理抽象化,简化了同步器的开发。
Step 2
Q:: AQS的主要组成部分有哪些?
A:: AQS主要由状态(state)、等待队列(FIFO queue)和两种资源获取方式(独占和共享)组成。状态用于表示同步状态,等待队列用于管理等待线程,独占和共享模式则定义了资源的获取方式。
Step 3
Q:: AQS是如何管理线程的?
A:: AQS使用一个FIFO等待队列来管理线程。当一个线程尝试获取锁但失败时,它会被放入等待队列中。线程被唤醒时,会从队列中取出并重新尝试获取锁。AQS通过CAS操作(Compare-And-
Swap)来确保线程安全。
Step 4
Q:: 什么是独占模式和共享模式?
A:: 独占模式(Exclusive)指只有一个线程能获取资源,例如ReentrantLock;共享模式(Shared)允许多个线程共享资源,例如CountDownLatch和Semaphore。AQS通过不同的模式来控制资源的访问方式。
Step 5
Q:: AQS中的状态是如何变化的?
A:: AQS中的状态使用一个整数变量来表示。通过CAS操作对状态进行修改,例如获取锁时状态增加,释放锁时状态减少。具体的状态值和含义取决于具体的同步器实现。
Step 6
Q:: 如何自定义一个同步器?
A:: 自定义同步器需要继承AQS并实现其抽象方法,如tryAcquire、tryRelease、tryAcquireShared和tryReleaseShared。这些方法定义了资源的获取和释放逻辑。通过这些方法,自定义同步器可以实现不同的同步策略。
Step 7
Q:: ReentrantLock是如何基于AQS实现的?
A:: ReentrantLock通过内部类Sync继承AQS,并实现了独占模式的资源获取和释放逻辑。在tryAcquire中,通过判断当前线程是否已经持有锁来决定是否增加锁的重入次数。在tryRelease中,减少锁的持有次数,当持有次数为0
时释放锁。