深入理解AQS:并发编程的基石
目录
一、什么是AQS?
1.1 AQS的核心地位
二、AQS核心架构
2.1 状态管理
三、AQS工作原理
3.1 同步队列管理
3.2 等待状态说明
四、AQS的两种模式
4.1 独占模式(Exclusive)
4.2 共享模式(Shared)
五、AQS在JUC中的应用
5.1 ReentrantLock实现
六、条件变量(Condition)
6.1 条件队列实现
七、AQS设计精髓
7.1 模板方法模式
7.2 无锁队列操作
八、总结
一、什么是AQS?
AQS(AbstractQueuedSynchronizer,抽象队列同步器)是Java并发包(JUC)的核心基础框架,它为实现各种同步器(如锁、信号量等)提供了一个通用的底层架构。
1.1 AQS的核心地位
- JUC的基石:
ReentrantLock
、CountDownLatch
、Semaphore
等都基于AQS构建 - 模板方法模式:定义了同步器的骨架,子类实现特定逻辑
- CLH队列:基于CLH锁变体的FIFO等待队列实现
二、AQS核心架构
2.1 状态管理
AQS使用一个volatile int state
来表示同步状态:
- ReentrantLock:state表示重入次数
- Semaphore:state表示可用许可数
三、AQS工作原理
3.1 同步队列管理
AQS使用CLH变体的FIFO双向队列管理等待线程:
static final class Node {volatile int waitStatus; // 等待状态volatile Node prev; // 前驱节点volatile Node next; // 后继节点 volatile Thread thread; // 关联线程Node nextWaiter; // 条件队列专用
}
3.2 等待状态说明
状态值 | 常量名 | 描述 |
0 | 初始状态 | 节点初始化时的状态 |
1 | CANCELLED | 节点因超时或中断被取消 |
-1 | SIGNAL | 后继节点需要被唤醒 |
-2 | CONDITION | 节点在条件队列中等待 |
-3 | PROPAGATE | 共享模式下传播释放 |
四、AQS的两种模式
4.1 独占模式(Exclusive)
// 获取资源
public final void acquire(int arg) {if (!tryAcquire(arg) &&acquireQueued(addWaiter(Node.EXCLUSIVE), arg))selfInterrupt();
}// 释放资源
public final boolean release(int arg) {if (tryRelease(arg)) {Node h = head;if (h != null && h.waitStatus != 0)unparkSuccessor(h);return true;}return false;
}
4.2 共享模式(Shared)
// 获取共享资源
public final void acquireShared(int arg) {if (tryAcquireShared(arg) < 0)doAcquireShared(arg);
}// 释放共享资源
public final boolean releaseShared(int arg) {if (tryReleaseShared(arg)) {doReleaseShared();return true;}return false;
}
五、AQS在JUC中的应用
5.1 ReentrantLock实现
// 非公平锁获取实现
final boolean nonfairTryAcquire(int acquires) {final Thread current = Thread.currentThread();int c = getState();if (c == 0) {if (compareAndSetState(0, acquires)) {setExclusiveOwnerThread(current);return true;}}else if (current == getExclusiveOwnerThread()) {int nextc = c + acquires;setState(nextc);return true;}return false;
}
六、条件变量(Condition)
6.1 条件队列实现
public class ConditionObject implements Condition {private transient Node firstWaiter; // 条件队列头private transient Node lastWaiter; // 条件队列尾public final void await() throws InterruptedException {if (Thread.interrupted())throw new InterruptedException();Node node = addConditionWaiter(); // 加入条件队列int savedState = fullyRelease(node); // 完全释放锁// ... 等待被signal唤醒}
}
七、AQS设计精髓
7.1 模板方法模式
public abstract class AbstractQueuedSynchronizer {// 子类需要实现的方法protected boolean tryAcquire(int arg) { throw new UnsupportedOperationException(); }protected boolean tryRelease(int arg) { throw new UnsupportedOperationException(); }// 模板方法public final void acquire(int arg) {if (!tryAcquire(arg) &&acquireQueued(addWaiter(Node.EXCLUSIVE), arg))selfInterrupt();}
}
7.2 无锁队列操作
AQS使用CAS操作维护队列:
// 节点入队
private Node addWaiter(Node mode) {Node node = new Node(Thread.currentThread(), mode);Node pred = tail;if (pred != null) {node.prev = pred;if (compareAndSetTail(pred, node)) {pred.next = node;return node;}}enq(node); // CAS失败时进入完整入队return node;
}
八、总结
AQS作为Java并发编程的基石,其设计体现了多个精妙之处:
- 模板方法模式:分离通用逻辑与特定实现
- CLH队列变体:高效管理等待线程
- 状态机设计:灵活支持多种同步器
- 无锁算法:CAS操作保证线程安全