news 2026/2/1 18:23:15

Java AQS 深度解析

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Java AQS 深度解析

一、AQS 是什么?

AQS(AbstractQueuedSynchronizer)是 Java 并发包的核心组件,可以把它想象成一个万能排队管理器。它管理着一个虚拟的排队队列,让线程能够有序地获取和释放资源。

核心思想:

  • 一个状态变量(state)表示资源数量
  • 一个 FIFO 队列管理等待线程
  • 提供获取/释放资源的模板方法

二、AQS 的核心结构

// 简化版 AQS 内部结构publicabstractclassAbstractQueuedSynchronizer{// 1. 状态变量 - 核心!privatevolatileintstate;// 2. 等待队列的节点staticfinalclassNode{Threadthread;// 等待的线程Nodeprev;// 前驱节点Nodenext;// 后继节点intwaitStatus;// 等待状态}// 3. 队列头尾privatetransientvolatileNodehead;privatetransientvolatileNodetail;}

三、AQS 的工作原理(比喻版)

想象一个公共厕所

  • state = 1:有一个坑位可用
  • 队列:等待上厕所的人排成的队伍
  • 每个人(线程)按顺序使用

四、实战示例:自己实现一个锁

1. 最简单的互斥锁实现

importjava.util.concurrent.locks.AbstractQueuedSynchronizer;importjava.util.concurrent.locks.Lock;importjava.util.concurrent.locks.ReentrantLock;/** * 自己实现的简易锁 - 基于 AQS */publicclassMySimpleLock{// 内部同步器privatestaticclassSyncextendsAbstractQueuedSynchronizer{// 尝试获取锁(CAS 设置 state 从 0 到 1)@OverrideprotectedbooleantryAcquire(intarg){// 使用 CAS 原子操作尝试获取锁if(compareAndSetState(0,1)){// 设置当前线程为独占所有者setExclusiveOwnerThread(Thread.currentThread());returntrue;}returnfalse;}// 尝试释放锁@OverrideprotectedbooleantryRelease(intarg){if(getState()==0){thrownewIllegalMonitorStateException();}// 清除独占所有者setExclusiveOwnerThread(null);// 注意:state 设置要在最后,保证可见性setState(0);returntrue;}// 是否被当前线程独占@OverrideprotectedbooleanisHeldExclusively(){returngetExclusiveOwnerThread()==Thread.currentThread();}}privatefinalSyncsync=newSync();publicvoidlock(){sync.acquire(1);// AQS 的模板方法}publicvoidunlock(){sync.release(1);// AQS 的模板方法}}

2. 测试我们的锁

publicclassAQSDemo{privatestaticintcount=0;privatestaticfinalMySimpleLocklock=newMySimpleLock();publicstaticvoidmain(String[]args)throwsInterruptedException{// 创建 10 个线程并发累加Thread[]threads=newThread[10];for(inti=0;i<10;i++){threads[i]=newThread(()->{for(intj=0;j<1000;j++){lock.lock();// 加锁try{count++;// 临界区操作}finally{lock.unlock();// 解锁}}});}// 启动所有线程for(Threadt:threads){t.start();}// 等待所有线程完成for(Threadt:threads){t.join();}System.out.println("最终结果: "+count);// 应该是 10000}}

五、可重入锁实现(像 ReentrantLock)

/** * 可重入锁实现 - 支持同一个线程重复加锁 */publicclassMyReentrantLock{privatestaticclassSyncextendsAbstractQueuedSynchronizer{// 获取锁@OverrideprotectedbooleantryAcquire(intacquires){Threadcurrent=Thread.currentThread();intc=getState();// 状态为 0,表示锁未被占用if(c==0){if(compareAndSetState(0,acquires)){setExclusiveOwnerThread(current);returntrue;}}// 锁已被占用,检查是否是当前线程(重入)elseif(current==getExclusiveOwnerThread()){intnextc=c+acquires;// 增加重入次数if(nextc<0){thrownewError("Maximum lock count exceeded");}setState(nextc);// 更新状态returntrue;}returnfalse;}// 释放锁@OverrideprotectedbooleantryRelease(intreleases){intc=getState()-releases;if(Thread.currentThread()!=getExclusiveOwnerThread()){thrownewIllegalMonitorStateException();}booleanfree=false;if(c==0){free=true;setExclusiveOwnerThread(null);}setState(c);returnfree;}// 创建 Condition 对象publicjava.util.concurrent.locks.ConditionnewCondition(){returnnewConditionObject();}}privatefinalSyncsync=newSync();publicvoidlock(){sync.acquire(1);}publicvoidunlock(){sync.release(1);}publicbooleantryLock(){returnsync.tryAcquire(1);}}

六、信号量实现(像 Semaphore)

/** * 信号量实现 - 控制同时访问的线程数 */publicclassMySemaphore{privatestaticclassSyncextendsAbstractQueuedSynchronizer{Sync(intpermits){setState(permits);// 初始化许可数量}// 获取许可@OverrideprotectedinttryAcquireShared(intacquires){for(;;){// 自旋intavailable=getState();intremaining=available-acquires;// 如果剩余许可不足,或者 CAS 成功if(remaining<0||compareAndSetState(available,remaining)){returnremaining;}}}// 释放许可@OverrideprotectedbooleantryReleaseShared(intreleases){for(;;){// 自旋intcurrent=getState();intnext=current+releases;if(next<current){thrownewError("Maximum permit count exceeded");}if(compareAndSetState(current,next)){returntrue;}}}}privatefinalSyncsync;publicMySemaphore(intpermits){sync=newSync(permits);}publicvoidacquire()throwsInterruptedException{sync.acquireSharedInterruptibly(1);}publicvoidrelease(){sync.releaseShared(1);}}

七、AQS 在 JDK 中的应用

publicclassAQSApplications{publicstaticvoidmain(String[]args){// 1. ReentrantLock - 可重入锁ReentrantLocklock=newReentrantLock();// 2. Semaphore - 信号量Semaphoresemaphore=newSemaphore(5);// 5个许可// 3. CountDownLatch - 倒计时门闩CountDownLatchlatch=newCountDownLatch(3);// 4. ReentrantReadWriteLock - 读写锁ReentrantReadWriteLockrwLock=newReentrantReadWriteLock();// 5. CyclicBarrier - 循环屏障CyclicBarrierbarrier=newCyclicBarrier(3);}}

八、AQS 的关键方法

获取资源的方法:

  • acquire(int arg)- 独占式获取,忽略中断
  • acquireInterruptibly(int arg)- 独占式获取,响应中断
  • tryAcquireNanos(int arg, long nanos)- 带超时的获取

释放资源的方法:

  • release(int arg)- 独占式释放

共享式方法:

  • acquireShared(int arg)- 共享式获取
  • releaseShared(int arg)- 共享式释放

九、AQS 的使用模式

// 自定义同步器的通用模式classCustomSyncextendsAbstractQueuedSynchronizer{// 通常需要实现的方法:// 1. tryAcquire/tryRelease - 独占模式// 2. tryAcquireShared/tryReleaseShared - 共享模式// 3. isHeldExclusively - 是否独占// 然后暴露给外部使用:publicvoidcustomLock(){acquire(1);}publicvoidcustomUnlock(){release(1);}}

十、总结与最佳实践

AQS 的核心要点:

  1. 状态 State:通过 volatile + CAS 实现原子更新
  2. 等待队列:CLH 队列的变体,公平管理线程排队
  3. 模板方法:子类只需实现 tryAcquire/tryRelease 等关键方法
  4. 两种模式:独占模式(如锁)、共享模式(如信号量)

为什么用 AQS?

  • 高效:避免了 Java 内置锁的重量级操作
  • 灵活:可以构建各种同步工具
  • 可靠:JDK 验证,生产就绪
  • 可控:可以自定义公平/非公平策略

使用建议:

  1. 优先使用 JDK 内置的并发工具(ReentrantLock, Semaphore等)
  2. 只有特殊需求时才自定义 AQS
  3. 理解底层原理有助于调试并发问题
  4. 注意锁的粒度,避免死锁

AQS 是 Java 并发编程的基石,理解它对于掌握 Java 高并发编程至关重要。虽然日常开发中不常直接使用,但了解其原理能让你更好地使用并发工具,并在面试中脱颖而出!

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/1/29 8:20:54

中文情感分析API:安全配置

中文情感分析API&#xff1a;安全配置 1. 背景与应用场景 在当前自然语言处理&#xff08;NLP&#xff09;广泛应用的背景下&#xff0c;中文情感分析已成为企业洞察用户反馈、监控舆情动态、优化客户服务的重要技术手段。无论是电商平台的商品评论、社交媒体的用户发言&…

作者头像 李华
网站建设 2026/1/30 16:25:47

StructBERT情感分析API集成:快速接入现有系统教程

StructBERT情感分析API集成&#xff1a;快速接入现有系统教程 1. 引言 1.1 中文情感分析的现实需求 在当今数字化运营环境中&#xff0c;用户评论、客服对话、社交媒体内容等非结构化文本数据呈爆炸式增长。如何从中高效提取情绪倾向&#xff0c;成为企业优化服务、监控舆情…

作者头像 李华
网站建设 2026/1/27 14:57:08

中文情感分析API:高可用设计

中文情感分析API&#xff1a;高可用设计 1. 背景与需求&#xff1a;中文情感分析的工程挑战 在自然语言处理&#xff08;NLP&#xff09;的实际应用中&#xff0c;情感分析是企业洞察用户反馈、监控舆情、优化客服系统的核心能力之一。尤其在中文语境下&#xff0c;由于语言结…

作者头像 李华
网站建设 2026/1/31 3:52:11

StructBERT轻量级情感分析:企业案例

StructBERT轻量级情感分析&#xff1a;企业案例 1. 中文情感分析的业务价值与挑战 在数字化转型加速的今天&#xff0c;企业每天都会产生海量的用户反馈数据——包括电商平台评论、客服对话记录、社交媒体舆情、问卷调查文本等。如何从这些非结构化中文文本中快速提取情绪倾向…

作者头像 李华
网站建设 2026/1/30 7:57:02

中文情感分析模型部署:StructBERT CPU优化版性能测试

中文情感分析模型部署&#xff1a;StructBERT CPU优化版性能测试 1. 背景与需求&#xff1a;中文情感分析的现实价值 在社交媒体、电商评论、客服对话等场景中&#xff0c;用户生成的中文文本蕴含着丰富的情绪信息。如何高效、准确地识别这些情绪倾向&#xff0c;已成为企业洞…

作者头像 李华