AQS 中的 Node 结构是线程等待队列的核心载体,通过双向链表组织、状态驱动和协作唤醒机制实现高效线程安全调度;包含 thread、prev/next、waitStatus 等关键字段,支持原子入队、头节点驱动唤醒及取消节点清理。

AQS 中的 Node 结构是线程等待队列的核心载体,它通过双向链表组织、状态驱动和协作唤醒机制,实现高效、线程安全的等待与调度。
Node 是等待队列的基本单元
每个等待锁(或资源)的线程都被封装成一个 Node 实例,挂入 AQS 维护的同步队列(CLH 变种双向链表)。Node 包含关键字段:
- thread:绑定当前等待的线程,唯一标识该节点语义
- prev / next:指向前驱和后继节点,构成双向链表,支持从任意节点定位头尾
-
waitStatus:反映节点生命周期状态,典型值有:
–1(SIGNAL):表示前驱节点释放锁后需唤醒本节点;
0:刚入队,尚未设置唤醒信号;
1(CANCELLED):因超时或中断被取消,后续会被跳过;
-2(CONDITION):仅用于条件队列,不在同步队列中生效
入队过程:原子性 + 自旋重试
当线程调用 acquire 失败后,会执行 addWaiter(Node.EXCLUSIVE) 入队:
- 先尝试一次 CAS 快速将新节点设为
tail;成功则完成入队 - 失败则进入
enq方法,通过死循环 + CAS 确保节点最终插入队尾 - 插入后,节点在
acquireQueued中自旋检查前驱是否为 head —— 若是,再次尝试获取锁;否则设置前驱的waitStatus = -1并调用LockSupport.park阻塞自身
出队与唤醒:头结点驱动,逐级传递
释放锁时,release 调用 unparkSuccessor 唤醒后继:
立即学习“Java免费学习笔记(深入)”;
- 先将 head 的
waitStatus设为 0(清除标记) - 从 tail 往前遍历,找到第一个
waitStatus <= 0的有效后继节点(跳过已取消节点) - 调用
LockSupport.unpark(node.thread)唤醒该线程 - 被唤醒线程重新竞争锁,若成功则把自己设为新的 head,并将原 head 从链表中“脱钩”(prev/next 置 null,帮助 GC)
取消与清理:保障队列健康
线程中断或超时时,会触发 cancelAcquire:
- 将节点
waitStatus设为 1(CANCELLED) - 跳过该节点,调整前后指针,使其在后续遍历中被自然忽略
- 避免无效节点堆积,维持队列响应效率


















