AbstractQueuedSynchronizer是Java并发编程中非常重要的基础类,位于java.util.concurrent.locks包下,它提供了一套通用的机制来实现依赖先进先出等待队列的阻塞锁和相关的同步器。很多我们日常使用的并发工具都基于AQS实现,比如ReentrantLock、Semaphore、ReentrantReadWriteLock等,理解AQS的工作原理能帮助我们更深入地掌握这些工具的实现逻辑。

AQS的核心结构
AQS的核心设计包含两个部分,一个是volatile修饰的int类型状态变量state,另一个是内置的先进先出双向等待队列,用来存放获取资源失败的线程。
状态变量state
state是AQS的核心控制变量,不同的同步器对state的含义有不同的定义。比如ReentrantLock中state表示锁的重入次数,state为0表示锁未被占用,大于0表示锁被占用且记录了重入次数;Semaphore中state表示剩余的许可证数量。
AQS提供了三个protected方法用来操作state:
- getState():获取当前state值
- setState(int newState):直接设置state值
- compareAndSetState(int expect, int update):使用CAS操作原子更新state值
等待队列
AQS的等待队列是一个双向链表,每个节点对应一个等待获取资源的线程。节点包含线程引用、等待状态等信息,队列的头节点是虚拟节点,不包含实际线程,真正的等待线程从第二个节点开始存放。
AQS的两种资源共享模式
AQS支持两种资源共享模式,子类同步器需要根据自己的需求选择其中一种实现对应的方法:
| 模式 | 说明 | 典型实现 |
|---|---|---|
| 独占模式 | 同一时间只有一个线程能获取资源,其他线程需要进入等待队列 | ReentrantLock |
| 共享模式 | 同一时间可以有多个线程获取资源,超过资源数量限制的线程进入等待队列 | Semaphore、CountDownLatch |
自定义同步器的实现步骤
如果要基于AQS实现自定义同步器,需要创建一个AQS的子类,然后根据选择的资源共享模式,重写对应的模板方法。AQS提供了以下需要重写的protected方法:
- tryAcquire(int arg):独占模式下尝试获取资源,成功返回true,失败返回false
- tryRelease(int arg):独占模式下尝试释放资源,成功返回true,失败返回false
- tryAcquireShared(int arg):共享模式下尝试获取资源,返回负数表示失败,0表示获取成功但没有剩余资源,正数表示获取成功且还有剩余资源
- tryReleaseShared(int arg):共享模式下尝试释放资源,成功返回true,失败返回false
- isHeldExclusively():判断当前同步器是否被独占,一般在独占模式下需要实现
实现独占模式的自定义锁
下面我们实现一个简单的独占锁,同一时间只允许一个线程持有锁,支持重入:
import java.util.concurrent.locks.AbstractQueuedSynchronizer;
import java.util.concurrent.locks.Lock;
// 自定义独占锁,基于AQS实现
public class CustomLock implements Lock {
// 内部同步器类,继承AQS
private static class Sync extends AbstractQueuedSynchronizer {
// 尝试获取锁,state为0表示锁未被占用
@Override
protected boolean tryAcquire(int arg) {
// 使用CAS将state从0更新为1,更新成功表示获取锁成功
if (compareAndSetState(0, arg)) {
// 设置当前持有锁的线程
setExclusiveOwnerThread(Thread.currentThread());
return true;
}
// 如果当前线程已经是锁的持有者,支持重入,增加state值
if (getExclusiveOwnerThread() == Thread.currentThread()) {
setState(getState() + arg);
return true;
}
return false;
}
// 尝试释放锁
@Override
protected boolean tryRelease(int arg) {
// 如果当前线程不是锁的持有者,抛出异常
if (getExclusiveOwnerThread() != Thread.currentThread()) {
throw new IllegalMonitorStateException();
}
// 减少state值
int nextState = getState() - arg;
boolean released = false;
// state减为0表示锁完全释放
if (nextState == 0) {
setExclusiveOwnerThread(null);
released = true;
}
setState(nextState);
return released;
}
// 判断锁是否被当前线程独占
@Override
protected boolean isHeldExclusively() {
return getExclusiveOwnerThread() == Thread.currentThread();
}
}
private final Sync sync = new Sync();
@Override
public void lock() {
// 调用AQS的acquire方法,会触发tryAcquire
sync.acquire(1);
}
@Override
public void lockInterruptibly() throws InterruptedException {
sync.acquireInterruptibly(1);
}
@Override
public boolean tryLock() {
return sync.tryAcquire(1);
}
@Override
public boolean tryLock(long time, java.util.concurrent.TimeUnit unit) throws InterruptedException {
return sync.tryAcquireNanos(1, unit.toNanos(time));
}
@Override
public void unlock() {
// 调用AQS的release方法,会触发tryRelease
sync.release(1);
}
@Override
public java.util.concurrent.locks.Condition newCondition() {
return sync.new ConditionObject();
}
}
自定义同步器的测试
我们可以编写一个简单的测试代码验证自定义锁的功能:
public class CustomLockTest {
private static int count = 0;
private static final CustomLock lock = new CustomLock();
public static void main(String[] args) throws InterruptedException {
// 创建10个线程对count进行累加
Thread[] threads = new Thread[10];
for (int i = 0; i < 10; i++) {
threads[i] = new Thread(() -> {
lock.lock();
try {
// 临界区操作,对count加1000
for (int j = 0; j < 1000; j++) {
count++;
}
} finally {
// 确保锁一定会被释放
lock.unlock();
}
});
}
// 启动所有线程
for (Thread thread : threads) {
thread.start();
}
// 等待所有线程执行完成
for (Thread thread : threads) {
thread.join();
}
// 最终结果应该是10000
System.out.println("最终count值:" + count);
}
}
运行上述测试代码,最终输出的count值为10000,说明我们的自定义独占锁正确地实现了线程同步功能。
AQS的工作流程总结
当线程尝试获取资源时,首先会调用我们重写的tryAcquire或tryAcquireShared方法,如果获取成功就直接返回;如果获取失败,AQS会把当前线程封装成节点加入等待队列的尾部,然后让线程进入阻塞状态。当持有资源的线程释放资源时,会调用我们重写的tryRelease或tryReleaseShared方法,释放成功后AQS会唤醒等待队列中的头节点后面的第一个等待线程,让它重新尝试获取资源。
理解AQS的这套工作流程,就能明白为什么基于它实现的同步器都能保证线程安全,也能根据业务需求灵活地实现各种自定义同步组件。
AbstractQueuedSynchronizerAQS自定义同步器Java并发修改时间:2026-07-16 15:42:41