aqs中线程挂起时状态为waiting或timed_waiting:调用park()进入waiting,调用parknanos()/parkuntil()进入timed_waiting;二者均不持有monitor锁,且与blocked无关,因挂起前已释放锁。

Java 中 AQS 队列里的线程在挂起时,处于 WAITING 或 TIMED_WAITING 状态,具体取决于挂起方式。
挂起状态由 LockSupport.park() 决定
AQS 使用 LockSupport.park()(或带超时的 parkNanos())来挂起线程。该方法会使线程进入:
-
WAITING:调用
park()无超时参数时,线程进入无限期等待,JVM 线程状态为 WAITING; -
TIMED_WAITING:调用
parkNanos(timeout)或parkUntil(deadline)时,线程进入带时限等待,状态为 TIMED_WAITING。
这不是 Object.wait() 的 WAITING(需持有 monitor),也不是 Thread.sleep() 的 TIMED_WAITING(不释放锁),而是基于 JVM 底层的“阻塞”语义——线程被操作系统线程调度器挂起,不消耗 CPU,且不持有任何 monitor 锁(AQS 挂起前已释放锁)。
与同步队列节点状态的对应关系
挂起动作发生在 AQS 同步队列中 waitStatus == SIGNAL 的节点上(表示“我挂起后,请唤醒我”)。但注意:
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
- 线程状态(
Thread.getState())是 JVM 层面的运行时视图,如 WAITING; - 节点 waitStatus(如
SIGNAL、CANCELLED)是 AQS 自定义的逻辑标记,用于控制唤醒流程; - 二者独立:一个节点 waitStatus 是 SIGNAL,不代表线程一定在 WAITING;它可能刚入队尚未挂起,也可能已被唤醒正在竞争锁。
为什么不是 BLOCKED?
BLOCKED 状态仅出现在线程**试图进入 synchronized 块但拿不到 monitor 锁**时。而 AQS 挂起发生在抢锁失败后主动调用 park(),此时线程已退出临界区、释放了锁,不再因锁竞争而阻塞,所以不会是 BLOCKED。
条件队列中的线程挂起状态
调用 Condition.await() 的线程会:
- 先释放当前持有的锁(state 修改 + 清除 owner);
- 将自身节点加入 Condition 单向队列,waitStatus 设为
CONDITION; - 再调用
LockSupport.park()—— 此时线程同样变为 WAITING 状态。
被 signal() 唤醒后,该节点会被转移到 AQS 同步队列尾部,随后参与锁竞争;若竞争失败,再次 park → 又一次进入 WAITING。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










