AQS 全称AbstractQueuedSynchronizer抽象队列同步器是 Java 并发包java.util.concurrent.locks的核心底层框架ReentrantLock、CountDownLatch、Semaphore等工具都是基于 AQS 实现的。简单说AQS 就是一套通用的锁/同步器实现模板解决了多线程竞争资源时的排队、阻塞、唤醒问题。一、AQS 核心三大组件AQS 底层就靠3 个东西实现所有同步逻辑1. 同步状态state 变量用一个volatile int state表示资源的占用状态state0资源空闲无线程占用state0资源已被占用重入锁时 state 会累加所有线程竞争锁本质就是修改这个 state 的值2. 双向链表CLH 同步队列存储抢锁失败的线程先进先出FIFO每个节点封装等待线程 等待状态 前驱/后继节点作用线程抢不到锁就进入队列排队不浪费 CPU3. 独占/共享模式AQS 支持两种同步模式开箱即用独占模式只有一个线程能持有锁ReentrantLock共享模式多个线程可同时持有锁CountDownLatch、Semaphore二、AQS 核心工作原理抢锁 排队 唤醒全流程我们以**独占锁ReentrantLock**为例走一遍完整流程步骤1线程尝试抢锁线程调用lock()→ 调用 AQS 的tryAcquire(arg)尝试修改statestate0用CAS原子修改为 1抢锁成功当前线程成为锁持有者state≠0如果是重入当前线程已持有锁state1依然成功抢锁失败 → 进入下一步步骤2抢锁失败加入同步队列排队把当前线程封装成一个Node 节点用CAS 安全地加入双向链表尾部调用LockSupport.park()阻塞当前线程让出 CPU步骤3锁释放唤醒排队线程持有锁的线程调用unlock()→ 执行state-1如果state0表示完全释放锁唤醒队列头部的第一个等待线程被唤醒的线程重新尝试抢锁成功则出队成为新的锁持有者三、AQS 关键技术细节1. 为什么用 volatile 修饰 state保证多线程之间的可见性一个线程修改 state其他线程立刻看到配合 CAS 实现无锁原子操作比synchronized更轻量2. 什么是 CAS全称Compare And Swap比较并交换作用原子性修改 state不加锁也能保证线程安全原理先比较内存值是否为预期值是就更新不是就失败重试3. 队列节点等待状态waitStatus节点的状态控制线程的阻塞/唤醒0默认状态SIGNAL(-1)后继节点需要被唤醒最常用CANCELLED(1)线程取消等待CONDITION(-2)在条件队列等待PROPAGATE(-3)共享模式下传播唤醒4. 公平锁 / 非公平锁AQS 天然支持两种锁策略非公平锁线程上来直接抢锁抢不到再排队ReentrantLock 默认✅ 优点吞吐量高❌ 缺点可能产生线程“饥饿”公平锁线程先看队列是否为空有排队线程就直接进队✅ 优点所有线程公平获取锁❌ 缺点性能稍低四、AQS 模板方法设计模式核心设计思想AQS 是抽象类它只做通用逻辑具体业务交给子类实现AQS 固定实现不用改线程入队、出队线程阻塞、唤醒队列维护CAS 修改 state子类必须实现定制逻辑子类只需要重写这几个方法tryAcquire()尝试获取独占锁tryRelease()尝试释放独占锁tryAcquireShared()尝试获取共享锁tryReleaseShared()尝试释放共享锁一句话总结AQS 搭骨架子类填逻辑极大简化了同步器开发。五、经典 AQS 实现类工具类模式核心原理ReentrantLock独占state0空闲state1占用重入时state1CountDownLatch共享state计数器countDown()减1减到0唤醒所有线程Semaphore共享state许可证数量acquire()拿证release()还证ReentrantReadWriteLock共享独占高16位读锁共享低16位写锁独占六、一句话总结 AQS 底层AQS 使用 volatile state 表示资源状态用 CLH 双向队列管理抢锁失败的线程通过 CAS 无锁操作 LockSupport 阻塞/唤醒实现了一套高可用的线程同步框架。总结核心三要素volatile state资源、CLH 队列排队、LockSupport阻塞唤醒核心流程尝试抢锁 → 失败入队阻塞 → 释放锁唤醒队首线程设计模式模板方法AQS 实现通用逻辑子类定制同步规则价值JUC 所有锁和同步工具的基石是 Java 高并发的核心底层
AQS底层原理
AQS 全称AbstractQueuedSynchronizer抽象队列同步器是 Java 并发包java.util.concurrent.locks的核心底层框架ReentrantLock、CountDownLatch、Semaphore等工具都是基于 AQS 实现的。简单说AQS 就是一套通用的锁/同步器实现模板解决了多线程竞争资源时的排队、阻塞、唤醒问题。一、AQS 核心三大组件AQS 底层就靠3 个东西实现所有同步逻辑1. 同步状态state 变量用一个volatile int state表示资源的占用状态state0资源空闲无线程占用state0资源已被占用重入锁时 state 会累加所有线程竞争锁本质就是修改这个 state 的值2. 双向链表CLH 同步队列存储抢锁失败的线程先进先出FIFO每个节点封装等待线程 等待状态 前驱/后继节点作用线程抢不到锁就进入队列排队不浪费 CPU3. 独占/共享模式AQS 支持两种同步模式开箱即用独占模式只有一个线程能持有锁ReentrantLock共享模式多个线程可同时持有锁CountDownLatch、Semaphore二、AQS 核心工作原理抢锁 排队 唤醒全流程我们以**独占锁ReentrantLock**为例走一遍完整流程步骤1线程尝试抢锁线程调用lock()→ 调用 AQS 的tryAcquire(arg)尝试修改statestate0用CAS原子修改为 1抢锁成功当前线程成为锁持有者state≠0如果是重入当前线程已持有锁state1依然成功抢锁失败 → 进入下一步步骤2抢锁失败加入同步队列排队把当前线程封装成一个Node 节点用CAS 安全地加入双向链表尾部调用LockSupport.park()阻塞当前线程让出 CPU步骤3锁释放唤醒排队线程持有锁的线程调用unlock()→ 执行state-1如果state0表示完全释放锁唤醒队列头部的第一个等待线程被唤醒的线程重新尝试抢锁成功则出队成为新的锁持有者三、AQS 关键技术细节1. 为什么用 volatile 修饰 state保证多线程之间的可见性一个线程修改 state其他线程立刻看到配合 CAS 实现无锁原子操作比synchronized更轻量2. 什么是 CAS全称Compare And Swap比较并交换作用原子性修改 state不加锁也能保证线程安全原理先比较内存值是否为预期值是就更新不是就失败重试3. 队列节点等待状态waitStatus节点的状态控制线程的阻塞/唤醒0默认状态SIGNAL(-1)后继节点需要被唤醒最常用CANCELLED(1)线程取消等待CONDITION(-2)在条件队列等待PROPAGATE(-3)共享模式下传播唤醒4. 公平锁 / 非公平锁AQS 天然支持两种锁策略非公平锁线程上来直接抢锁抢不到再排队ReentrantLock 默认✅ 优点吞吐量高❌ 缺点可能产生线程“饥饿”公平锁线程先看队列是否为空有排队线程就直接进队✅ 优点所有线程公平获取锁❌ 缺点性能稍低四、AQS 模板方法设计模式核心设计思想AQS 是抽象类它只做通用逻辑具体业务交给子类实现AQS 固定实现不用改线程入队、出队线程阻塞、唤醒队列维护CAS 修改 state子类必须实现定制逻辑子类只需要重写这几个方法tryAcquire()尝试获取独占锁tryRelease()尝试释放独占锁tryAcquireShared()尝试获取共享锁tryReleaseShared()尝试释放共享锁一句话总结AQS 搭骨架子类填逻辑极大简化了同步器开发。五、经典 AQS 实现类工具类模式核心原理ReentrantLock独占state0空闲state1占用重入时state1CountDownLatch共享state计数器countDown()减1减到0唤醒所有线程Semaphore共享state许可证数量acquire()拿证release()还证ReentrantReadWriteLock共享独占高16位读锁共享低16位写锁独占六、一句话总结 AQS 底层AQS 使用 volatile state 表示资源状态用 CLH 双向队列管理抢锁失败的线程通过 CAS 无锁操作 LockSupport 阻塞/唤醒实现了一套高可用的线程同步框架。总结核心三要素volatile state资源、CLH 队列排队、LockSupport阻塞唤醒核心流程尝试抢锁 → 失败入队阻塞 → 释放锁唤醒队首线程设计模式模板方法AQS 实现通用逻辑子类定制同步规则价值JUC 所有锁和同步工具的基石是 Java 高并发的核心底层