面试题:说说 AQS 吧?

当然可以,AQS(AbstractQueuedSynchronizer) 是 Java 并发包 java.util.concurrent(简称 JUC)中非常核心的一个抽象类,是构建各种同步器(如 ReentrantLockSemaphoreCountDownLatchReentrantReadWriteLock 等)的基础框架。


一、AQS 的作用

AQS 的核心思想是:使用一个 int 类型的原子变量 state 来表示同步状态,并通过一个 FIFO 队列来管理等待获取锁的线程

它提供了一套模板方法,允许子类通过实现特定的方法(如 tryAcquiretryRelease)来定义同步语义,从而构建各种不同的同步组件。


二、AQS 的核心组成

1. 同步状态(state)

  • state 是一个 volatile 修饰的 int 类型变量,用于表示同步资源的状态。
  • 子类通过修改 state 的值来控制资源的获取与释放。
  • AQS 提供了基于 CAS 的原子操作方法(如 compareAndSetState)来修改 state,确保线程安全。

2. 同步队列(CLH 队列)

  • AQS 内部维护了一个双向链表的同步队列(FIFO),用于管理等待获取锁的线程。
  • 每个节点(Node)代表一个线程,包含线程引用、等待状态、前驱节点和后继节点等信息。
  • 当线程尝试获取锁失败时,会被封装成一个 Node 插入到队列尾部,并进入等待状态。

3. Node 节点的状态(waitStatus)

每个 Node 有一个 waitStatus 字段,表示节点的等待状态,常见值如下:

状态值含义
0默认状态,当前节点在队列中,等待获取锁
CANCELLED(1)当前线程被取消(可能因超时或中断)
SIGNAL(-1)后续节点需要被唤醒
CONDITION(-2)当前节点在条件队列中
PROPAGATE(-3)表示释放共享锁时应传播唤醒操作(用于共享模式)

三、AQS 的两种模式

AQS 支持两种同步模式:

1. 独占模式(Exclusive Mode)

  • 一次只能有一个线程获取同步资源。
  • 适用于 ReentrantLockReentrantReadWriteLock.WriteLock 等。
  • 相关方法:acquire()release()

2. 共享模式(Shared Mode)

  • 多个线程可以同时获取同步资源。
  • 适用于 CountDownLatchSemaphoreReentrantReadWriteLock.ReadLock 等。
  • 相关方法:acquireShared()releaseShared()

四、AQS 的核心方法(模板方法)

AQS 提供了一系列公共方法,这些方法调用了子类实现的 钩子方法(如 tryAcquiretryRelease)。主要方法如下:

方法名说明
acquire(int arg)独占方式获取同步状态,失败则进入队列等待
release(int arg)独占方式释放同步状态,唤醒后继节点
acquireShared(int arg)共享方式获取同步状态,失败则进入队列等待
releaseShared(int arg)共享方式释放同步状态,唤醒后继节点

这些方法内部调用了子类必须实现的钩子方法:

钩子方法说明
tryAcquire(int arg)独占方式尝试获取资源
tryRelease(int arg)独占方式尝试释放资源
tryAcquireShared(int arg)共享方式尝试获取资源
tryReleaseShared(int arg)共享方式尝试释放资源

五、AQS 的典型应用场景

同步组件使用方式AQS 模式说明
ReentrantLock独占锁独占模式可重入、支持公平/非公平
Semaphore信号量共享模式控制同时访问的线程数量
CountDownLatch倒计时门闩共享模式所有线程等待一个倒计时完成
ReentrantReadWriteLock读写锁独占 + 共享读共享,写独占
FutureTask异步任务独占用于异步执行任务并获取结果

六、AQS 的优缺点

✅ 优点

  • 高度抽象:提供统一的同步框架,简化了同步组件的开发。
  • 高效性:基于 CAS 和队列管理,性能优秀。
  • 灵活性:支持独占和共享两种模式,适用于多种同步场景。
  • 可扩展性强:开发者可以基于 AQS 自定义同步组件。

❌ 缺点

  • 理解成本高:内部逻辑复杂,涉及队列、CAS、线程状态管理等知识。
  • 调试困难:死锁、阻塞等问题不容易排查。

七、总结

项目说明
核心机制使用 state 表示同步状态,FIFO 队列管理等待线程
同步模式独占模式、共享模式
实现方式基于 CAS + volatile + 线程阻塞
核心设计模板方法 + 钩子方法
应用场景ReentrantLockSemaphoreCountDownLatch
优势高效、灵活、可扩展
难点实现复杂,调试困难

八、一句话总结 AQS:

AQS 是 Java 并发包中构建各种同步组件的核心框架,它通过一个原子状态变量和一个等待队列,实现了对线程的阻塞与唤醒机制,为开发者提供了统一的同步抽象模型。

如果你正在准备面试,建议结合 ReentrantLockCountDownLatch 的源码,深入理解 AQS 的工作原理,这样可以更好地回答并发相关问题。

THE END
喜欢就支持一下吧
点赞11 分享