aqs中state变量声明为private volatile int state,volatile保障可见性与有序性,cas保证修改原子性,二者协同实现线程安全。

Java AQS(AbstractQueuedSynchronizer)中的 state 变量确实是用 volatile 修饰的,但不是直接写成 volatile int state —— 它实际是通过 Unsafe 的原子操作 + volatile 语义间接保障可见性和有序性,而字段本身在源码中**声明为 volatile**。
state 字段在 AQS 中的声明方式
AQS 类中定义了如下字段:
private volatile int state;
这是标准、合法的 volatile 修饰。JDK 源码(如 JDK 8/11/17)中确实如此声明。它满足 volatile 的两个核心语义:
-
可见性:一个线程对
state的修改,对其他线程立即可见; -
禁止重排序:编译器和 CPU 不会将对
state的读写与其他内存操作随意重排(如构造函数初始化后才发布对象)。
为什么仅靠 volatile 不够?还需要 CAS
volatile 保证单次读/写的可见性与有序性,但不保证复合操作的原子性。例如 state++ 是“读-改-写”三步,存在竞态。
AQS 依赖 Unsafe.compareAndSwapInt(CAS)实现原子更新,而 CAS 的底层实现本身就要求目标字段具有 volatile 语义(否则可能读到过期缓存值)。所以:
-
volatile是 CAS 正确工作的基础前提; - CAS 提供原子性,
volatile提供可见性与 happens-before 保证; - 二者配合,才能安全实现锁获取、释放、条件队列唤醒等逻辑。
volatile 如何参与 AQS 的同步逻辑
以 acquire(int arg) 流程为例:
- 调用
tryAcquire(arg)前,会先读一次state—— volatile 读确保看到最新值; - 若需入队,
addWaiter和acquireQueued中反复检查state,每次读都是 volatile 读; - 唤醒后继节点时(如
unparkSuccessor),也是基于当前state判断是否可抢占,volatile 读防止误判。
注意:volatile 并不等于线程安全,只是基石
仅声明 volatile int state 并不能让 AQS 正常工作。真正保证同步的是:
- 所有状态变更都走
setState/compareAndSetState等受控方法; - 这些方法内部调用
Unsafe的 volatile 写或 CAS 操作; - 上层同步器(如
ReentrantLock)严格遵循 AQS 的 tryAcquire/tryRelease 协议。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











