谈谈你对AQS的理解
                           
天天向上
发布: 2025-07-12 12:41:46

原创
232 人浏览过

AbstractQueuedSynchronizer(简称 AQS)是 Java 并发包 java.util.concurrent 的核心基础组件之一,尤其是构建自定义同步器(如锁、信号量、栅栏等)的基础框架。理解 AQS 是深入掌握 Java 并发编程的关键步骤之一。


一、AQS 是什么?

AQS 全称:AbstractQueuedSynchronizer
是 Java 并发包中定义的一个用于构建锁和同步器的基础框架类,其核心原理是:以一个 int 状态值(state)和一个 FIFO 双向等待队列为基础,来控制线程的并发访问。

AQS 主要通过**“状态位 + 队列”实现线程之间的同步与通信**。


二、核心结构与关键点

组成部分描述
state表示同步状态(例如是否已加锁)
exclusive owner thread独占模式下记录当前持有锁的线程
CLH 队列FIFO 等待队列,保存获取同步状态失败的线程
Node队列中的元素,每个等待线程对应一个 Node 节点
compareAndSetState使用 CAS 原子操作保证线程安全

AQS 支持两种同步模式:

模式描述示例
独占(Exclusive)同一时间只允许一个线程获取资源ReentrantLock
共享(Shared)同一资源可被多个线程共享CountDownLatch、Semaphore

三、工作机制原理(独占模式)

ReentrantLock(独占) 为例,简化流程如下:

  1. 线程尝试通过 tryAcquire() 获取锁
  2. 如果获取失败(即 state != 0),则构造 Node 节点加入 AQS 的等待队列
  3. 后续线程通过 acquire() 不断尝试获取锁
  4. 当前线程释放锁时调用 release(),并通知(unpark)下一个等待线程尝试获取锁

📌 AQS 不直接实现同步器逻辑,而是通过 模板方法模式,子类(如 ReentrantLock)需实现:

protected boolean tryAcquire(int arg);
protected boolean tryRelease(int arg);

四、核心方法解析(核心骨架)

1、独占模式核心方法

public final void acquire(int arg)
public final boolean release(int arg)
  • acquire():尝试获取锁(失败则入队)
  • release():释放锁并唤醒下一个节点

2、共享模式核心方法

public final void acquireShared(int arg)
public final boolean releaseShared(int arg)
  • 用于支持多个线程共享资源(如信号量)

五、典型实现示例(基于 AQS)

同步工具使用模式说明
ReentrantLock独占可重入锁
Semaphore共享控制并发线程数
CountDownLatch共享等待其他线程完成
ReentrantReadWriteLock共享+独占读共享,写独占
FutureTask独占控制任务执行一次性完成

六、深入关键点

1. CLH 队列(链表队列)

AQS 使用了 CLH(Craig, Landin, and Hagersten)队列实现线程的排队等待,具有非阻塞、自旋的特性:

head → Node1 → Node2 → Node3 → ...

每个 Node 包含:

  • thread:线程本身
  • waitStatus:等待状态(如 SIGNAL, CANCELLED, CONDITION
  • prev/next:前后指针

2. 状态变量 state

  • 所有同步器的核心状态都保存在 int state 中;
  • 子类通过 getState() / setState() / compareAndSetState() 操作;
  • 支持多重加锁(重入锁)计数(如信号量 permits);

3. CAS 保证线程安全

protected final boolean compareAndSetState(int expect, int update)

AQS 依赖底层 Unsafe 类的 CAS 实现(Compare And Swap),避免加锁开销,实现非阻塞并发控制。


七、实战案例:自定义独占锁

class MyLock extends AbstractQueuedSynchronizer {
    public boolean tryAcquire(int acquires) {
        if (compareAndSetState(0, acquires)) {
            setExclusiveOwnerThread(Thread.currentThread());
            return true;
        }
        return false;
    }

    protected boolean tryRelease(int releases) {
        setExclusiveOwnerThread(null);
        setState(0);
        return true;
    }

    public void lock() {
        acquire(1);
    }

    public void unlock() {
        release(1);
    }
}

八、相关源码入口(JDK)


九、学习资料推荐

  1. 《Java 并发编程实战》 – Brian Goetz
  2. 《深入理解 Java 虚拟机》 – 周志明
  3. JDK 官方文档:
    🔗 https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/locks/AbstractQueuedSynchronizer.html
  4. AQS 可视化图解:
    https://tech.meituan.com/2019/12/05/aqs-theory-and-apply.html (推荐阅读)

十、总结:AQS 的优缺点

优点缺点
统一并发控制框架,灵活性高学习曲线陡峭
支持独占、共享模式切换不易调试(底层依赖 CAS、自旋)
高性能、非阻塞使用不当容易死锁

更多详细内容请关注其他相关文章!

发表回复 0

Your email address will not be published. Required fields are marked *