首页IT科技并发逻辑漏洞(并发基础之AQS)

并发逻辑漏洞(并发基础之AQS)

时间2025-07-14 21:04:06分类IT科技浏览3575
导读:目录...

目录

什么AQS

AQS原理

重点1:CLH队列​

重点2:state 状态

AQS 两种资源共享方式

1) Exclusive(独占)

2) Share(共享)

AQS 模板方法运用

补充知识CAS

CAS的优点

CAS的缺点

缺点解决办法

总结

什么AQS

AQS是位于java.util.concurrent.locks 包下的 AbstractQueuedSynchronizer类              ,是构建同步器和锁的基础框架              。我们可以通过继承AbstractQueuedSynchronizer 创建自己的同步器                    。比如我们常用的JUC并发包下面的CountDownLatch              、ReentrantLock                    、Semaphore等等都是源于AQS实现的并发工具类      。

AQS原理

核心思想是多个线程访问共享资源                    ,如果一个线程发现共享资源没有被占用      ,则将资源设定为锁定状态且当前线程设为占用线程       ,如果一个线程发现共享资源已经被占用                    ,则需要等待占用线程释放资源             ,当然当占用线程释放资源的时候AQS会通知其他等待线程进行资源抢占       。在AQS实际源码中是通过state 状态在标识资源是否占用       ,通过CLH FIFO虚拟双向队列来实现将最近的等待线程放在队列末尾                    。

重点1:CLH队列

如图所示CLH是一个虚拟的双向队列                    ,是通过state的值实现线程等待排序在队列末尾             。队列head 头部是当前资源占用工作线程             ,node1-node n 则是资源被锁定后等待的线程节点       。在实际的资源占用过程中,根据是否公平锁来确定是顺序占用资源和抢占式占用资源                    。

重点2:state 状态

如上图所示                    ,线程获取资源是否被占用是通过获取 state 状态来实现             。AQS源码已经给出获取      、设置       、通过CAS修改state 的方法。此时我们可以理解为:

 1                    、线程获取state 发现为 0                    ,说明没有线程占用则占用该资源,并通过CAS将state 置为 1

2             、如果该线程有重入的情况则继续增加state 的值              ,重入几次就增加几次

3       、线程出方法则需要释放state值                   ,也就是减少state

4                    、当state值为0 的时候标识线程执行完毕解除占用      ,此时AQS唤醒其他线程可以占用资源

AQS 两种资源共享方式

1) Exclusive(独占)

只有一个线程能执行              ,如 ReentrantLock                    。又可分为公平锁和非公平锁,ReentrantLock 同时支持两种锁                   。根据ReentrantLock定义                    ,我们可知公平锁是根据队列的等待顺序占用资源      ,非公平锁是所有的等待线程抢占资源。

2) Share(共享)

运行多个线程对资源共享       ,比如JUC并发工具CountDownLatch             、Semaphore等都是运行多个线程访问资源              。

AQS 模板方法运用

AQS内置很多的操作方法                    ,比如获取锁 tryAcquire()、释放锁 tryRelease()                    、超时获取tryAcquireNanos()                   、响应中断 acquireInterruptibly()等操作方法

在实际的运用过程中             ,我们可以直接继承AQS从而轻易的获取这些方法来实现我们的同步器                   。

当前JUC下的并发工具类都是基于AQS来实现自己的功能的       ,我们现在来鉴赏一下      。

比如可重入锁ReentrantLock                    ,我们进入源码查看             ,ReentrantLock内部类继承AQS:

我们ReentrantLock超时获取锁/释放锁也都是调用AQS超时获取锁/释放锁的方法:

当然其他对资源状态和队列的操作方法都是基于AQS实现的,对于JUC中其他的并发工具类也是如此                    ,都是基于AQS实现              。

补充知识CAS

CAS是Compare and Swap 的缩写                   ,也就是比较和替换,是JUC最核心最基础的理论                    。原理是基于三个数据 主存值V、线程副本值A              、需要修改为值B      。当且仅当主存值V等于线程副本值A的时候              ,才能将数据修改为B       。

CAS的优点

CAS是乐观锁                   ,且一直自旋等待锁      ,所以性能很高                    。

CAS的缺点

ABA问题              ,如果我们先将值C修改为D,再修改为C                    ,CAS会认为此数据没有修改             。

缺点解决办法

1                   、加版本号

2      、JAVA JUC atomic下提供AtomicStampedReference包装类

总结

AQS是位于java.util.concurrent.locks 包下的 AbstractQueuedSynchronizer类      ,是构建同步器和锁的基础框架       。JAVA JUC并发包下的工具类都是基于AQS实现       ,其原理都是通过state状态来确定线程是否占用资源                    ,未拿到锁的线程则放置在CLH虚拟双向队列末尾             ,后续通过AQS通知抢占资源                    。

创心域SEO版权声明:以上内容作者已申请原创保护,未经允许不得转载,侵权必究!授权事宜、对本内容有异议或投诉,敬请联系网站管理员,我们将尽快回复您,谢谢合作!

展开全文READ MORE
seo搜索排名优化公司(掌握SEO排名优化,让你的网站闪耀成为搜索引擎宠儿) 前端依赖包是什么(前端设计模式——依赖注入模式)