Java 并发面试题, 说说 AQS 吧?
Java 并发面试题, 说说 AQS 吧?
QA
Step 1
Q:: 说说 AQS 吧?
A:: AQS (AbstractQueuedSynchronizer)
是 Java 并发包中用于构建锁和同步器的基础框架。它通过一个先进先出(FIFO)队列来管理线程的获取和释放。AQS 主要通过两种方式进行同步:独占模式(如 ReentrantLock)和共享模式(如 CountDownLatch)。在独占模式下,只有一个线程可以获取资源;而在共享模式下,多个线程可以同时获取资源。AQS 提供了丰富的 API 和灵活的扩展性,使得开发人员可以方便地实现自定义的同步器。
Step 2
Q:: AQS 的核心机制是什么?
A:: AQS 的核心机制包括以下几点:
1.
State:一个 volatile 变量,用于表示当前的同步状态。
2.
FIFO 队列:通过 Node 类实现,用于保存等待获取资源的线程。
3.
CAS 操作:通过 compareAndSet 方法原子性地更新 state 变量,确保线程安全。
4.
自定义同步器:通过继承 AQS 并重写其模板方法(如 tryAcquire、tryRelease)来实现不同的同步策略。
Step 3
Q:: 如何使用 AQS 实现一个自定义锁?
A:: 实现一个自定义锁需要以下步骤:
1.
继承 AbstractQueuedSynchronizer 类。
2.
实现 tryAcquire 和 tryRelease 方法,用于定义获取和释放锁的逻辑。
3.
实现 lock 和 unlock 方法,调用 AQS 提供的 acquire 和 release 方法。
4.
可以根据需要实现 Condition 接口来支持条件变量。示例如下:
class CustomLock extends AbstractQueuedSynchronizer {
@Override
protected boolean tryAcquire(int arg) {
if (compareAndSetState(0, 1)) {
setExclusiveOwnerThread(Thread.currentThread());
return true;
}
return false;
}
@Override
protected boolean tryRelease(int arg) {
setExclusiveOwnerThread(null);
setState(0);
return true;
}
public void lock() { acquire(1); }
public void unlock() { release(1); }
}
Step 4
Q:: AQS 支持的同步模式有哪些?
A:: AQS 支持两种同步模式:
1.
独占模式(Exclusive):在这种模式下,只有一个线程可以访问资源。例如 ReentrantLock 就是基于这种模式实现的。
2.
共享模式(Shared):在这种模式下,多个线程可以同时访问资源。例如 CountDownLatch、Semaphore 和 CyclicBarrier 就是基于这种模式实现的。
Step 5
Q:: AQS 的 Node 结构是什么样的?
A:: AQS 的 Node 结构是一个内部类,包含以下字段:
1.
thread:当前节点代表的线程。
2.
nextWaiter:指向下一个节点,形成一个队列。
3.
waitStatus:表示节点的等待状态,如 SIGNAL、CANCELLED 等。
4.
prev 和 next:用于构成双向链表,形成同步队列。Node 主要用于管理和控制线程的排队和唤醒。