KMS智能激活:告别Windows和Office激活烦恼的一站式解决方案
2026/6/3 13:54:04
AQS = AbstractQueuedSynchronizer
它是一个抽象类,提供了一套基于 FIFO 阻塞队列 + 原子状态管理的框架,让你能轻松实现各种自定义的同步工具。
state):表示资源是否可用(如锁是否被占用、计数器剩余值等)。ReentrantLock)。Semaphore、CountDownLatch)。💡AQS 本身不定义“同步语义”,而是把“如何判断能否获取资源”、“如何释放资源”这些逻辑留给子类实现。
volatile int state表示同步状态。protectedfinalintgetState()protectedfinalvoidsetState(intnewState)protectedfinalbooleancompareAndSetState(intexpect,intupdate)// CASstate来表达自己的业务含义:ReentrantLock:0=未锁,1=已锁(重入次数)Semaphore:表示剩余许可数量CountDownLatch:表示倒计数值AQS 使用一个双向链表(Node 链表)来管理等待线程:
head → [Node1] ↔ [Node2] ↔ [Node3] ← tail每个Node包含:
thread:等待的线程waitStatus:节点状态(如SIGNAL=-1表示需要被唤醒)prev/next:前后指针nextWaiter:用于区分是独占还是共享模式(或用于 Condition)⚠️ 注意:这是一个CLH 队列的变种,原始 CLH 用于自旋锁,而 AQS 用于阻塞锁,所以增加了
next指针便于唤醒后继。
| 模式 | 方法 | 说明 |
|---|---|---|
| 独占(Exclusive) | tryAcquire()tryRelease() | 成功则获得排他权限(如写锁) |
| 共享(Shared) | tryAcquireShared()tryReleaseShared() | 返回值 ≥0 表示成功,可多线程并发(如读锁、信号量) |
🔄 共享模式下,释放资源时可能级联唤醒多个线程(因为多个线程可能同时满足条件)。
publicfinalvoidacquire(intarg){if(!tryAcquire(arg)&&acquireQueued(addWaiter(Node.EXCLUSIVE),arg))selfInterrupt();}tryAcquire()(由子类实现)。addWaiter()将当前线程封装成Node加入队尾。acquireQueued():在队列中自旋,直到被前驱唤醒且自己成为头节点后再次尝试获取。publicfinalbooleanrelease(intarg){if(tryRelease(arg)){// 子类实现Nodeh=head;if(h!=null&&h.waitStatus!=0)unparkSuccessor(h);// 唤醒后继returntrue;}returnfalse;}unparkSuccessor()唤醒下一个等待线程。🔍
unparkSuccessor()会从tail往前找第一个非取消的节点(处理中间节点被中断/超时的情况)。
你不能直接使用 AQS,而是继承它并实现以下方法(根据需求选):
| 方法 | 用途 | 必须实现? |
|---|---|---|
tryAcquire(int) | 独占式获取 | 是(如果支持独占) |
tryRelease(int) | 独占式释放 | 是 |
tryAcquireShared(int) | 共享式获取 | 是(如果支持共享) |
tryReleaseShared(int) | 共享式释放 | 是 |
isHeldExclusively() | 当前线程是否独占持有 | 是(如果要用Condition) |
✅ 所有这些方法都必须是无阻塞、线程安全、短小精悍的!
staticclassSyncextendsAbstractQueuedSynchronizer{protectedbooleantryAcquire(intacquires){if(compareAndSetState(0,1)){setExclusiveOwnerThread(Thread.currentThread());returntrue;}returnfalse;}protectedbooleantryRelease(intreleases){setState(0);setExclusiveOwnerThread(null);returntrue;}protectedbooleanisHeldExclusively(){returngetState()==1;}}staticclassSyncextendsAbstractQueuedSynchronizer{protectedinttryAcquireShared(intignore){returngetState()==1?1:-1;// 1=已触发,-1=需等待}protectedbooleantryReleaseShared(intignore){setState(1);returntrue;// 唤醒所有等待者}}tryAcquire中加判断:if(hasQueuedPredecessors())returnfalse;// 有排队者就别插队new ConditionObject()创建条件变量。isHeldExclusively()和正确的release/acquire逻辑。acquireInterruptibly、tryAcquireNanos等方法,子类只需调用即可。“Don’t call us, we’ll call you.” — Hollywood Principle
这使得你可以用几十行代码实现出工业级的同步器,而无需操心底层并发细节。
如果你正在学习 JUC 或想深入理解ReentrantLock、Semaphore等的原理,掌握 AQS 是必经之路。它的设计堪称 Java 并发编程的“皇冠上的明珠”。
如需进一步分析某个具体同步器(比如ReentrantReadWriteLock如何用 AQS 实现读写锁),欢迎继续提问!