AQS 是 ReentrantLock 的核心引擎,通过 volatile int state 管理锁状态、双向链表实现同步队列、LockSupport 控制线程阻塞与唤醒,并通过 tryAcquire/tryRelease 等钩子方法将锁语义注入框架。

Java 中 AQS 是 ReentrantLock 实现高效锁管理的核心引擎,它不靠 JVM 特殊指令,仅用 volatile int state + 双向链表队列 + LockSupport 就撑起了整个锁机制。它的高效不在于“快”,而在于“稳、准、可定制”——把状态管理、排队逻辑、线程调度这三类重复性高、易出错的底层工作全部封装好,让 ReentrantLock 只需专注定义“什么算拿到锁”“什么算释放完”,其余全由 AQS 自动调度。
state 状态变量:轻量又精确的锁计数器
ReentrantLock 的可重入性完全依赖 AQS 的 volatile int state 字段:
- state = 0 表示锁空闲,任何线程都可尝试抢占
- state > 0 表示已被占用,数值即当前持有线程的重入次数
- 每次 lock() 成功,state 原子递增;每次 unlock() 成功,state 原子递减
- volatile 保证多核 CPU 下的可见性,CAS 操作(如 compareAndSetState)确保修改原子性
同步队列:公平与非公平的底层分水岭
AQS 维护一个 FIFO 双向链表(CLH 队列变种),所有抢锁失败的线程都会被封装为 Node 加入队列尾部:
- 非公平模式:抢锁前先直接 CAS 尝试一次 state,成功就跳过排队——这就是“插队”,吞吐更高
- 公平模式:抢锁前先检查队列是否为空或自己是否排在头节点后,只允许“按序获取”,避免饥饿但性能略低
- Node 的 waitStatus 字段(如 SIGNAL、CANCELLED)精准控制唤醒时机和节点生命周期
线程阻塞与唤醒:用 park/unpark 精准控流
AQS 不使用 Object.wait/notify 这类重量级机制,而是基于 Unsafe.park 和 unpark 实现毫秒级响应:
立即学习“Java免费学习笔记(深入)”;
- 线程入队后立即 park,进入 WAITING 状态,不消耗 CPU
- 前驱节点释放锁时,会 unpark 其 next 节点(即真正要唤醒的线程)
- lockInterruptibly() 能响应中断,是因为 park 可被 interrupt 打断并抛出 InterruptedException
- tryLock(timeout) 则是 parkNanos + 超时检测组合实现
钩子方法:ReentrantLock 定义语义,AQS 执行流程
ReentrantLock 通过继承 AQS 并重写几个关键钩子方法,把业务语义注入框架:
- tryAcquire(int acquires):定义“怎样才算成功获取锁”——检查 state、判断是否重入、设置 exclusiveOwnerThread
- tryRelease(int releases):定义“怎样才算彻底释放锁”——state 减到 0 才清空 exclusiveOwnerThread
- isHeldExclusively():用于 Condition 等场景,判断当前线程是否独占持有锁
- 这些方法由 AQS 在 acquire/release 流程中自动调用,用户无需接触队列操作或线程调度


















