AQS本质是“排队+状态管理”基础设施,用volatile state记录资源状态、CLH双向队列管理等待线程、模板方法交由子类实现判据;加锁时CAS失败则入队挂起,解锁后唤醒后继;支持独占/共享模式、公平/非公平策略、中断响应及条件队列。

回答AQS面试题拿满分,关键不是堆砌术语,而是讲清楚“它为什么这样设计”和“它怎么支撑不同工具”。面试官想确认你是否真正理解底层逻辑,而不是背答案。
先说本质:别只报名字,要讲清角色
AQS不是锁本身,而是一套通用的“排队+状态管理”基础设施。它干三件事:
- 用一个volatile int state记录资源状态(比如ReentrantLock里是重入次数,Semaphore里是剩余许可数)
- 用一个FIFO双向链表(CLH变种)存等待线程,每个节点(Node)封装线程、状态(SIGNAL/CANCELLED等)、前后指针
- 提供模板方法(如tryAcquire/tryRelease),把“怎么判能否抢到锁”留给子类实现,自己只管排队、挂起、唤醒
再讲流程:用一句话串起加锁和解锁动作
加锁时:线程先调tryAcquire尝试CAS修改state;失败就包装成Node入队尾,然后LockSupport.park()挂起自己;解锁时:调tryRelease更新state,成功后unpark队列head的下一个节点,被唤醒的线程再试一次tryAcquire。
这个过程里没有“轮询”,靠的是waitStatus = SIGNAL标记前驱节点有责任唤醒后继——这是避免空转的关键细节。
立即学习“Java免费学习笔记(深入)”;
区分模式:独占 vs 共享不能混为一谈
独占模式(如ReentrantLock):只允许一个线程持有资源,对应acquire/release和tryAcquire/tryRelease;
共享模式(如CountDownLatch、Semaphore):允许多个线程同时通过,对应acquireShared/releaseShared和tryAcquireShared/tryReleaseShared;
注意:共享模式下,一个线程释放资源可能唤醒多个等待者(比如countDown后所有await线程都被放行),所以tryReleaseShared返回值是int,用于控制是否继续传播唤醒。
补上亮点:公平性、中断、条件队列这些加分项
公平锁和非公平锁的区别不在队列结构,而在tryAcquire的实现逻辑:非公平锁会插队——state为0时直接CAS抢,不管队列有没有人;公平锁则先查hasQueuedPredecessors(),确保没人排在前面才去抢。
如果被问“可中断吗”,答:AQS原生支持。acquireInterruptibly内部会检查线程中断状态,park前先校验,被中断直接抛InterruptedException;条件队列(ConditionObject)则是AQS的扩展,用来实现await/signal,它维护独立的单向链表,和同步队列分离。


















