抽象队列同步器
时间: 2025-06-07 16:18:12 浏览: 25
### 抽象队列同步器 AQS 的原理与实现
#### 1. AQS 的定义与作用
AQS(AbstractQueuedSynchronizer)是 Java 并发包 `java.util.concurrent` 中的一个核心组件,它提供了一种框架化的机制来构建锁和其他同步工具。AQS 使用了一个基于 FIFO 的双向链表队列来管理线程之间的竞争关系,并通过状态变量控制线程的同步行为[^1]。
#### 2. 核心组成部分
##### (1)状态变量(state)
AQS 维护一个名为 `state` 的整型变量,用来表示同步状态。不同的子类可以通过原子操作修改这个变量以反映资源的占有情况。例如,在 ReentrantLock 中,`state` 表示当前锁被持有的次数;而在 Semaphore 中,`state` 则代表剩余信号量的数量[^3]。
##### (2)CLH 队列
为了高效地处理大量线程的竞争,AQS 内部采用 CLH(Craig, Landin, and Hagersten locks)变体形式的队列结构。当一个线程试图获取锁失败时,会被封装成节点加入到该队列中等待下一次机会。每个节点包含了指向前后相邻节点的指针以及一些标志位用于记录自身的状况[^4]。
#### 3. 主要方法分类
根据职责划分,AQS 定义了一系列模板方法供开发者覆盖实现:
- **独占模式 vs 共享模式**
- 独占模式意味着同一时刻只有一个线程能成功获得许可执行关键路径上的代码片段。
- 共享模式允许多个线程同时持有相同的权限级别而不违反约束条件。
- **tryAcquire/tryRelease 系列函数**
这些是非公平版本下的尝试性接口,默认情况下不考虑排队顺序直接抢夺资源使用权。如果调用者满足准入资格则返回 true ,否则 false 。对于释放动作而言则是更新内部计数器并将可能唤醒下一个候选者[^2]。
- **acquire/acquireShared 方法族**
正常途径进入临界区的方式分为两类:一是完全遵循既定规则逐级向上申请直至达成目的为止;二是允许一定程度上的投机取巧即所谓的“乐观锁定策略”。
- **release/releaseShared 函数组**
类似于上面提到的内容只不过方向反转过来而已——前者是从拥有权角度出发逐步削减直到彻底放弃掌控权;后者强调集体利益最大化原则之下共同退让部分权益给后来者享用[^2]。
#### 4. 锁定机制详解
以下是有关如何运用 AQS 构建自定义同步原语的一些简单例子:
```java
public class MyMutex extends AbstractQueuedSynchronizer {
protected boolean tryAcquire(int acquires) {
if (compareAndSetState(0, 1)) { // CAS 更新 state 值
setExclusiveOwnerThread(Thread.currentThread());
return true;
}
return false;
}
protected boolean tryRelease(int releases) {
if (getState() == 0) throw new IllegalMonitorStateException();
setState(0); // 清零恢复初始态
setExclusiveOwnerThread(null); // 解绑当前所有者信息
return true; // 返回值决定是否通知后续待命成员
}
public void lock() {
acquire(1);
}
public void unlock() {
release(1);
}
}
```
上述代码展示了怎样借助 AQS 来模拟互斥锁的行为特性。其中重点在于重写两个虚基类提供的纯虚函数分别对应加锁解锁两阶段的操作逻辑[^3]。
---
###
阅读全文
相关推荐















