Lazy loaded image
AQS的作用和基本原理是什么?
字数 628阅读时长≈ 2 分钟
2026-10-14
type
Post
status
Published
date
Oct 14, 2026
slug
aqs
summary
tags
技术探索
category
手写
icon
password
AQS(AbstractQueuedSynchronizer,抽象队列同步器)是 Java 实现锁和同步器的基础框架,比如 ReentrantLock、Semaphore、CountDownLatch。
它的核心原理是 一个 state 状态变量 + CAS + FIFO 等待队列。
state:管理同步状态,比如锁是否被占用、剩余许可证数量。
CAS:通过原子操作修改 state,保证并发安全。
FIFO 等待队列:管理等待线程,线程获取资源失败后进入等待队列,通过 LockSupport 挂起,等待被唤醒后重新尝试获取。

为什么能用于多种同步器?

因为 AQS 就是一个专门抽象出来的同步器框架,把通用的排队、阻塞、唤醒机制封装好了,子类只需要实现不同的资源获取和释放逻辑,就能构建不同的同步器。
同步器
state 的含义
核心区别
ReentrantLock
锁的重入次数
独占模式,一个线程持有
Semaphore
剩余许可证数量
共享模式,允许多个线程获得许可
CountDownLatch
剩余计数
计数归零后允许等待线程通过
关键在于:AQS 提供统一的机制,不同同步器定义不同的 state 语义和获取、释放规则。

ReentrantLock 如何与 AQS 交互?加锁和释放时,内部如何操作状态与等待队列?

1. 加锁 lock()
  • 锁空闲(state = 0):线程通过 CAS 把 state 从 0 改为 1,并记录自己为锁持有者,加锁成功。
  • 同一线程再次加锁:state 加 1,实现可重入。
  • 其他线程加锁失败:进入 AQS 等待队列,必要时通过 LockSupport.park() 挂起。
2. 解锁 unlock()
  • 持有锁的线程将 state 减 1。
  • 如果 state 仍大于 0,说明还有重入层数,锁不释放。
  • 如果 state 减到 0,清除持有者,真正释放锁,AQS 唤醒等待队列中的后继线程,让它重新竞争锁。

二、具体例子

假设线程 A、B 竞争同一把 ReentrantLock:
notion image

公平锁和非公平锁区别在哪?

公平锁:获取锁前检查 AQS 队列中是否有线程排在自己前面,避免插队。
非公平锁:允许新线程直接竞争空闲锁,即使已有线程排队。
回到首页