news 2026/4/26 8:54:32

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/4/26 23:28:02

中文情感分析API集成指南:StructBERT调用最佳实践

中文情感分析API集成指南&#xff1a;StructBERT调用最佳实践 1. 引言&#xff1a;中文情感分析的现实价值与技术挑战 在社交媒体、电商评论、客服对话等场景中&#xff0c;用户生成内容&#xff08;UGC&#xff09;蕴含着丰富的情感信息。如何自动识别这些文本中的情绪倾向—…

作者头像 李华
网站建设 2026/4/24 13:46:30

StructBERT轻量CPU版部署:情感分析服务搭建步骤详解

StructBERT轻量CPU版部署&#xff1a;情感分析服务搭建步骤详解 1. 中文情感分析的应用价值与挑战 在当今数字化时代&#xff0c;用户生成内容&#xff08;UGC&#xff09;呈爆炸式增长&#xff0c;社交媒体、电商平台、客服系统中每天产生海量的中文文本数据。如何从中快速提…

作者头像 李华
网站建设 2026/4/23 6:37:53

AI实体分析论文复现指南:云端1:1环境,避免踩坑

AI实体分析论文复现指南&#xff1a;云端1:1环境&#xff0c;避免踩坑 引言 作为一名研究生&#xff0c;复现顶会论文的算法是提升科研能力的重要途径。但很多同学都遇到过这样的困境&#xff1a;明明按照论文描述一步步操作&#xff0c;结果却与原作者相差甚远。这种情况往往…

作者头像 李华
网站建设 2026/4/26 7:35:47

StructBERT WebUI功能扩展:批量分析模式实现

StructBERT WebUI功能扩展&#xff1a;批量分析模式实现 1. 背景与需求驱动 随着自然语言处理技术在实际业务场景中的广泛应用&#xff0c;情感分析已成为客服质检、舆情监控、用户反馈挖掘等领域的核心能力之一。当前主流的中文情感分析服务多依赖高性能GPU环境&#xff0c;…

作者头像 李华
网站建设 2026/4/22 6:31:22

StructBERT实战:客服系统

StructBERT实战&#xff1a;客服系统中的中文情感分析 1. 项目背景与技术选型 1.1 中文情感分析的业务价值 在现代智能客服系统中&#xff0c;用户情绪识别已成为提升服务质量的关键能力。无论是电商平台、金融客服还是政务热线&#xff0c;能够实时判断用户语句的情感倾向&…

作者头像 李华
网站建设 2026/4/26 8:31:47

AI智能体自动化测试:持续集成方案,比人工测试快100倍

AI智能体自动化测试&#xff1a;持续集成方案&#xff0c;比人工测试快100倍 1. 为什么需要AI智能体自动化测试 想象一下这样的场景&#xff1a;每次产品更新后&#xff0c;QA团队需要手动执行上千个测试用例&#xff0c;耗时长达两周。这不仅延迟了发布周期&#xff0c;还让…

作者头像 李华