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 高并发编程至关重要。虽然日常开发中不常直接使用,但了解其原理能让你更好地使用并发工具,并在面试中脱颖而出!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/1144958.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

实战案例分享】台达伺服CANopen通信实例:详细资料齐全,采购单、接线图、驱动器参数设置、P...

台达伺服canopen案例&#xff0c;现场实际设备使用&#xff0c;单独写的总线型伺服通信的例子。 资料齐全&#xff0c;有采购单&#xff0c;接线图&#xff0c;伺服驱动器参数设置&#xff0c;PLC程序&#xff0c;触摸屏程序。 例子通俗易懂&#xff0c;程序中文注释。去年车间…

StructBERT情感分析模型:保姆级指南

StructBERT情感分析模型&#xff1a;保姆级指南 1. 引言&#xff1a;中文情感分析的现实需求 在当今信息爆炸的时代&#xff0c;中文互联网每天产生海量的用户评论、社交媒体内容和产品反馈。如何从这些非结构化文本中快速提取情绪倾向&#xff0c;成为企业洞察用户心声、优化…

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

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

GTE中文语义相似度服务入门教程:5分钟快速体验

GTE中文语义相似度服务入门教程&#xff1a;5分钟快速体验 1. 引言 在自然语言处理&#xff08;NLP&#xff09;领域&#xff0c;语义相似度计算是理解文本间关系的核心任务之一。无论是智能客服中的意图匹配、推荐系统中的内容去重&#xff0c;还是搜索引擎的查询扩展&#…

OpenAI免费开源!电脑截图神器~支持OCR文字识别、截图、贴图、录屏、AI对话翻译、GIF动图等等,内置Deepseek、同义千问大模型,电脑必备工具!

下载链接 https://tool.nineya.com/s/1jbuat867 软件介绍 OpenAI免费开源&#xff01;电脑截图神器~支持OCR文字识别、截图、贴图、录屏、AI对话翻译、GIF动图等等&#xff0c;内置Deepseek、同义千问大模型&#xff0c;电脑必备工具&#xff01; 软件特点 免费开源的电脑架…

StructBERT模型测试数据:构建方法论

StructBERT模型测试数据&#xff1a;构建方法论 1. 中文情感分析的应用价值与挑战 在自然语言处理&#xff08;NLP&#xff09;领域&#xff0c;情感分析&#xff08;Sentiment Analysis&#xff09;是理解用户意图、挖掘舆情信息的核心技术之一。尤其在中文语境下&#xff0…

StructBERT情感分析WebUI

StructBERT情感分析WebUI&#xff1a;轻量级中文情感识别服务部署实践 1. 背景与需求&#xff1a;为什么需要本地化中文情感分析&#xff1f; 在当前自然语言处理&#xff08;NLP&#xff09;广泛应用的背景下&#xff0c;情感分析已成为智能客服、舆情监控、用户评论挖掘等场…

AI实体侦测效率革命:云端比本地快8倍实测

AI实体侦测效率革命&#xff1a;云端比本地快8倍实测 1. 为什么云端AI实体侦测能快8倍&#xff1f; 想象一下&#xff0c;你用家里的普通电脑处理一段1小时的监控视频&#xff0c;需要整整8小时才能完成AI实体识别。这就像用自行车送快递&#xff0c;虽然能完成任务&#xff…

StructBERT轻量优化:低资源环境部署方案

StructBERT轻量优化&#xff1a;低资源环境部署方案 1. 背景与挑战&#xff1a;中文情感分析的现实需求 在当前自然语言处理&#xff08;NLP&#xff09;应用中&#xff0c;中文情感分析已成为智能客服、舆情监控、用户评论挖掘等场景的核心能力。然而&#xff0c;许多实际部…

情感分析系统自动化运维:StructBERT

情感分析系统自动化运维&#xff1a;StructBERT 1. 引言&#xff1a;中文情感分析的现实需求与挑战 在社交媒体、电商评论、客服对话等大量用户生成内容&#xff08;UGC&#xff09;场景中&#xff0c;中文情感分析已成为企业洞察用户情绪、优化产品服务的关键技术手段。传统…

UEBA技术深度体验:1小时1块快速验证效果

UEBA技术深度体验&#xff1a;1小时1块快速验证效果 1. UEBA技术是什么&#xff1f;为什么SOC分析师需要它&#xff1f; UEBA&#xff08;用户和实体行为分析&#xff09;就像给企业安全系统装上一个"行为测谎仪"。它通过AI学习每个员工、设备的正常行为模式&#…

StructBERT轻量版部署:企业级解决方案

StructBERT轻量版部署&#xff1a;企业级解决方案 1. 中文情感分析的业务价值与挑战 在当今数字化时代&#xff0c;用户生成内容&#xff08;UGC&#xff09;呈爆炸式增长&#xff0c;社交媒体、电商评论、客服对话等场景中蕴含着海量的情感信息。对企业而言&#xff0c;快速…

StructBERT部署教程:新闻评论情感分析系统

StructBERT部署教程&#xff1a;新闻评论情感分析系统 1. 引言 1.1 中文情感分析的现实需求 在社交媒体、电商平台和新闻评论区中&#xff0c;每天都会产生海量的中文用户反馈。如何从这些非结构化文本中快速识别公众情绪倾向&#xff0c;已成为企业舆情监控、产品优化和服务…

DeepSeek-V3漏洞挖掘教程:MacBook用户福音,云端GPU救星

DeepSeek-V3漏洞挖掘教程&#xff1a;MacBook用户福音&#xff0c;云端GPU救星 1. 为什么MacBook用户需要云端GPU&#xff1f; 作为一名白帽子黑客&#xff0c;你可能经常遇到这样的场景&#xff1a;在星巴克发现了一个新的漏洞挖掘工具&#xff0c;兴奋地打开MacBook Pro准备…

Mac用户福音:用云端GPU跑AI侦测模型,告别显卡焦虑

Mac用户福音&#xff1a;用云端GPU跑AI侦测模型&#xff0c;告别显卡焦虑 1. 为什么Mac用户需要云端GPU解决方案 作为一名Mac用户&#xff0c;特别是设计师或开发者&#xff0c;你可能遇到过这样的困境&#xff1a;最新的AI模型需要强大的GPU支持&#xff0c;但MacBook的M系列…

快速上架第一个智能体

简介 Coze&#xff08;官网&#xff1a;https://www.coze.cn/home&#xff09;&#xff0c;是字节跳动出品的&#xff0c;一个 AI Agent 开发平台&#xff0c;在该平台上可以将自己调试完成&#xff0c;开发好的智能体上架到他们的商店&#xff0c;分享给其他人使用&#xff0…

AI智能实体侦测数据预处理:告别本地跑崩,云端省心办

AI智能实体侦测数据预处理&#xff1a;告别本地跑崩&#xff0c;云端省心办 1. 为什么你需要云端数据预处理&#xff1f; 作为一名数据分析师&#xff0c;处理TB级安全日志可能是你的日常噩梦。想象一下&#xff1a;在公司电脑上运行一个特征提取脚本&#xff0c;等待3天后—…

中文情感分析WebUI开发:StructBERT轻量版详解

中文情感分析WebUI开发&#xff1a;StructBERT轻量版详解 1. 引言&#xff1a;中文情感分析的现实需求与挑战 在社交媒体、电商评论、用户反馈等场景中&#xff0c;中文文本的情感倾向蕴含着丰富的用户情绪信息。传统的人工筛选方式效率低下&#xff0c;难以应对海量数据。因…

基于PLC的立体车库设计(源码+万字报告+讲解)(支持资料、图片参考_相关定制)

基于PLC的立体车库设计 摘要 伴随着自动化技术的发展和创新&#xff0c;我国工业发展得到了质的飞跃&#xff0c;社会高速发展的同时&#xff0c;停车难也成为了一二线城市中普遍存在的问题&#xff0c;解决群众停车问题已经成为智能建筑领域新的研究方向。建立立体车库对解决这…

AI智能体语音交互案例:云端GPU 10分钟部署,成本1块

AI智能体语音交互案例&#xff1a;云端GPU 10分钟部署&#xff0c;成本1块 引言&#xff1a;创业公司的AI演示困境与破局方案 作为一家语音交互领域的创业公司&#xff0c;向投资人展示产品原型是融资过程中的关键环节。但很多团队都面临这样的困境&#xff1a;开发了功能强大…