网站制作代理查电商软件下载
2026/1/9 10:25:22 网站建设 项目流程
网站制作代理,查电商软件下载,网站页数,工作室设计#x1f511; 一、AQS 是什么#xff1f;——“同步器的骨架”AQS AbstractQueuedSynchronizer 它是一个抽象类#xff0c;提供了一套基于 FIFO 阻塞队列 原子状态管理的框架#xff0c;让你能轻松实现各种自定义的同步工具。✅ 核心能力#xff1a; 管理一个整型状态 一、AQS 是什么——“同步器的骨架”AQS AbstractQueuedSynchronizer它是一个抽象类提供了一套基于 FIFO 阻塞队列 原子状态管理的框架让你能轻松实现各种自定义的同步工具。✅ 核心能力管理一个整型状态state表示资源是否可用如锁是否被占用、计数器剩余值等。维护一个 FIFO 等待队列当线程获取资源失败时自动入队并阻塞释放资源时唤醒队列中的下一个线程。支持独占模式exclusive和共享模式shared独占同一时刻只能一个线程持有如ReentrantLock。共享多个线程可同时持有如Semaphore、CountDownLatch。AQS 本身不定义“同步语义”而是把“如何判断能否获取资源”、“如何释放资源”这些逻辑留给子类实现。 二、AQS 的核心机制1.状态管理State通过volatile int state表示同步状态。提供三个方法操作它protectedfinalintgetState()protectedfinalvoidsetState(intnewState)protectedfinalbooleancompareAndSetState(intexpect,intupdate)// CAS子类通过这个state来表达自己的业务含义ReentrantLock0未锁1已锁重入次数Semaphore表示剩余许可数量CountDownLatch表示倒计数值2.FIFO 等待队列CLH 变种AQS 使用一个双向链表Node 链表来管理等待线程head → [Node1] ↔ [Node2] ↔ [Node3] ← tail每个Node包含thread等待的线程waitStatus节点状态如SIGNAL-1表示需要被唤醒prev/next前后指针nextWaiter用于区分是独占还是共享模式或用于 Condition⚠️ 注意这是一个CLH 队列的变种原始 CLH 用于自旋锁而 AQS 用于阻塞锁所以增加了next指针便于唤醒后继。3.两种模式独占 vs 共享模式方法说明独占ExclusivetryAcquire()tryRelease()成功则获得排他权限如写锁共享SharedtryAcquireShared()tryReleaseShared()返回值 ≥0 表示成功可多线程并发如读锁、信号量 共享模式下释放资源时可能级联唤醒多个线程因为多个线程可能同时满足条件。 三、关键流程解析▶ 获取资源以独占为例publicfinalvoidacquire(intarg){if(!tryAcquire(arg)acquireQueued(addWaiter(Node.EXCLUSIVE),arg))selfInterrupt();}先尝试tryAcquire()由子类实现。如果失败调用addWaiter()将当前线程封装成Node加入队尾。调用acquireQueued()在队列中自旋直到被前驱唤醒且自己成为头节点后再次尝试获取。▶ 释放资源独占publicfinalbooleanrelease(intarg){if(tryRelease(arg)){// 子类实现Nodehhead;if(h!nullh.waitStatus!0)unparkSuccessor(h);// 唤醒后继returntrue;}returnfalse;}成功释放后调用unparkSuccessor()唤醒下一个等待线程。unparkSuccessor()会从tail往前找第一个非取消的节点处理中间节点被中断/超时的情况。️ 四、如何使用 AQS——子类必须实现的方法你不能直接使用 AQS而是继承它并实现以下方法根据需求选方法用途必须实现tryAcquire(int)独占式获取是如果支持独占tryRelease(int)独占式释放是tryAcquireShared(int)共享式获取是如果支持共享tryReleaseShared(int)共享式释放是isHeldExclusively()当前线程是否独占持有是如果要用Condition✅ 所有这些方法都必须是无阻塞、线程安全、短小精悍的 五、经典例子回顾例1非重入互斥锁MutexstaticclassSyncextendsAbstractQueuedSynchronizer{protectedbooleantryAcquire(intacquires){if(compareAndSetState(0,1)){setExclusiveOwnerThread(Thread.currentThread());returntrue;}returnfalse;}protectedbooleantryRelease(intreleases){setState(0);setExclusiveOwnerThread(null);returntrue;}protectedbooleanisHeldExclusively(){returngetState()1;}}例2一次性门闩BooleanLatchstaticclassSyncextendsAbstractQueuedSynchronizer{protectedinttryAcquireShared(intignore){returngetState()1?1:-1;// 1已触发-1需等待}protectedbooleantryReleaseShared(intignore){setState(1);returntrue;// 唤醒所有等待者}} 六、高级特性1.公平性控制默认是非公平的允许“插队”新线程可能在排队线程之前抢到锁。实现公平锁在tryAcquire中加判断if(hasQueuedPredecessors())returnfalse;// 有排队者就别插队2.Condition 支持通过new ConditionObject()创建条件变量。必须实现isHeldExclusively()和正确的release/acquire逻辑。3.可中断、超时支持AQS 提供了acquireInterruptibly、tryAcquireNanos等方法子类只需调用即可。✅ 总结AQS 的设计哲学“Don’t call us, we’ll call you.” — Hollywood PrincipleAQS 负责队列管理、线程阻塞/唤醒、状态原子性、中断/超时处理。你子类负责定义“什么是获取成功”、“什么是释放成功”。这使得你可以用几十行代码实现出工业级的同步器而无需操心底层并发细节。如果你正在学习 JUC 或想深入理解ReentrantLock、Semaphore等的原理掌握 AQS 是必经之路。它的设计堪称 Java 并发编程的“皇冠上的明珠”。如需进一步分析某个具体同步器比如ReentrantReadWriteLock如何用 AQS 实现读写锁欢迎继续提问

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询