一、预备
Hello!感谢能看菜鸡阿昌的文章 ๑•̀ㅂ•́)و✧
这几天在学习阳哥的AQS,发现他简直就是艺术品。
这里记录一下AQS的核心执行流程。我们以ReentrantLock为例子,进行突破。
因为AQS涉及到Juc的知识,所以这里需要有一些前置知识如下: ≡ω≡
- Juc知识
- LockSupport
- 模版设计模式
- 重入锁/自旋锁
- CAS
- Unsafe
如果不晓得,请自行去补以上的知识,再看一下的内容
也是建议打开IDEA进行源码调试一起食用极佳
二、前言
1、什么是AQS
字面意思
- 英文缩写:
Abstract Queued Synchronizer - 中文直译:
抽象队列同步器
- 英文缩写:
技术解释
AQS = 资源变量State +双向虚拟队列FIFO
简单解释
通过一个资源state,来表示锁的状态。0是自由状态,大于0代表被占用。抢不到资源的线程,就放在FIFO队列中进行管理,争取下次再进行争取获取资源
2、那为什么要学AQS呢
Juc线程流程控制&锁的底层实现的基础,如:
- ReentrantLock
- CountDownLatch
- ReentrantReadWriteLock
- Semaphore
- 等…..
3、ReentrantLock与AQS的关系
- ReentrantLock类继承实现图
ReentrantLock中存在一个内部类Sync,他继承了AQS,所以ReentrantLock是通过构造内聚Sync类,来间接实现AQS的内容。

- 任何一个Lock接口的实现类,内部都是【聚合】了一个【队列同步器】的子类完成线程访问控制的

4、AQS的内部体系关系
下面是我精炼出来的内部体系关系内容:省略了很多
1 | public abstract class AbstractQueuedSynchronizer{//AQS |
上面会看到,AQS中会将线程进行包装成一个Node节点,它有前/后节点。这里就会发现他没有一个真正的双向队列,而是通过包装线程为Node类,并指定里面前后的指向,用前/后节点指针指向来实现一个虚拟的双向队列。
5、AQS同步队列的基本结构

三、正文
我们这里以两个线程抢资源锁为例,测试代码如下:
1 | public static void main(String[] args) { |
按照main执行流程下来,假设main线程先创建线程A,那么肯定先会执行lock.lock(),让我们看看lock()方法的底层到底做了什么,是如何通过AQS去让线程之间阻塞执行的。
1、线程A开始抢锁
①lock()

进来他先会执行sync的lock()方法

那我们上面已经知道了sync对象是Sync类,内聚变量,一开始并未对齐初始化。

那我们开始创建ReentrantLock对象的时候,就会对Sync进行初始化,以上是以无参构造器举例(默认是非公平锁)

因此,我们上面执行的sync.lock()会去执行Sync的lock()方法,而lock()方法是一个抽象方法

所以就会去执行我们无参构造给初始化的NonfairSync的lock()方法。

首先进入lock()方法,他会进行if-else判断,进行执行compareAndSetState(0,1)
②compareAndSetState()
我们看方法的命名,就知道他必然是CAS方法,他肯定是调用unsafe工具包直接操作内存地址的。
![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-vmqLbZE8-1641015862564)(../AppData/Roaming/Typora/typora-user-images/image-20220101110824640.png)]](https://img-blog.csdnimg.cn/b5e164510f79442e851b305edb016852.png)
1 | //CAS,预期的的值是0,想要更新为1 |
如果此时队列同步器AQS的state资源变量的值是0,那么就更新为1,且该操作是原子操作。再上面,我们说了state资源变量的默认值为0,那这里的CAS操作必然是成功的。就会修改完成后返回true。
![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-hW9fW6yb-1641015862565)(../AppData/Roaming/Typora/typora-user-images/image-20220101111540775.png)]](https://img-blog.csdnimg.cn/4cf7c39538e94a3ebe161492c4b653a1.png)
compareAndSetState(0, 1)返回的是true,所以就会继续往下执行setExclusiveOwnerThread(Thread.currentThread())
③setExclusiveOwnerThread()
![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-eoCXrolS-1641015862567)(../AppData/Roaming/Typora/typora-user-images/image-20220101111716424.png)]](https://img-blog.csdnimg.cn/be78cccdf8f2461cab397ddce06e4436.png?x-oss-process=image/watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA6Zi_5piM5Zac5qyi5ZCD6buE5qGD,size_15,color_FFFFFF,t_70,g_se,x_16)
看这个名字都能看出来,他是设置排他Exclusive的拥有者线程是哪个
![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-BALmNuPR-1641015862568)(../AppData/Roaming/Typora/typora-user-images/image-20220101111736436.png)]](https://img-blog.csdnimg.cn/42e3e96f793043848881dd0331356923.png)
设置占有线程,逻辑也很简单,就是将Thread exclusiveOwnerThread变量设置为当前线程,代表此时的队列同步器处理器占有的线程的是此时进来的线程A。
![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-KzNvvxSL-1641015862570)(../AppData/Roaming/Typora/typora-user-images/image-20220101111936210.png)]](https://img-blog.csdnimg.cn/723d1a457e8d45f98d732ff1285dc6ae.png?x-oss-process=image/watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA6Zi_5piM5Zac5qyi5ZCD6buE5qGD,size_15,color_FFFFFF,t_70,g_se,x_16)
那执行完,这里的lock()逻辑就完毕返回了,接下来就会执行业务逻辑,这里我们模拟是业务执行过长时间,线程A一直持有锁。
那么此时的全局状态图应该是如下:

线程A去强占资源,state资源变量通过CAS操作从0修改为1。setExclusiveOwnerThread()设置了当前AQS同步队列的占有线程为线程A
2、线程B开始抢锁
![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-hN7AHYra-1641015862573)(../AppData/Roaming/Typora/typora-user-images/image-20220101113049488.png)]](https://img-blog.csdnimg.cn/b01b9f6a36a14cf1890c3f9408bd9a10.png?x-oss-process=image/watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA6Zi_5piM5Zac5qyi5ZCD6buE5qGD,size_10,color_FFFFFF,t_70,g_se,x_16)
线程B肯定有会像上面的线程A一样去执行lock()方法
①lock()
![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-1lbtyZxG-1641015862575)(../AppData/Roaming/Typora/typora-user-images/image-20220101113114294.png)]](https://img-blog.csdnimg.cn/0a3c294fd0e74312b9c0e64826f4feb2.png)
同样,他会执行到lock()方法,也会去先执行compareAndSetState()。
![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-bhmbRWcd-1641015862580)(../AppData/Roaming/Typora/typora-user-images/image-20220101113259399.png)]](https://img-blog.csdnimg.cn/5397dc3344d4436480865508c2fbd2b2.png)
但是此时传入的参数为0,1。即期望为0,更新为1的操作,但是此时state变量已经被占用了,且因为线程A被CAS修改为1,那么结果很不意外的,compareAndSetState必然返回false,则就不会进入setExclusiveOwnerThread去改变此时AQS的拥有线程,因为此时线程A正在占用。
![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-mC4lUXCS-1641015862584)(../AppData/Roaming/Typora/typora-user-images/image-20220101113511646.png)]](https://img-blog.csdnimg.cn/09cc3c9a30f2463d9744b717169b006d.png)
那么,他就会去执行acquire(1)的方法
②acquire()
![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-mC4lUXCS-1641015862584)(../AppData/Roaming/Typora/typora-user-images/image-20220101113511646.png)]](https://img-blog.csdnimg.cn/09cc3c9a30f2463d9744b717169b006d.png)
因为上面,直接CAS操作失败了,那么就会执行acquire。
上面会看到3个重要方法:
- tryAcquire()
- addWaiter()
- acquireQueued()
③tryAcquire()

一点开,会发现,他上来就给抛了个UnsupportedOperationException异常,那就会很明显的看出来,这里使用的模版设计模式,必须要实现抽象的AbstractQueuedSynchronizer的tryAcquire方法。因为我们用的默认的空参构造器,所以初始化Sync用的是NonfairSync。进入之后他就会执行nonfairTryAcquire()
④nonfairTryAcquire()

1 | final boolean nonfairTryAcquire(int acquires) { |

因为此时state的状态为1,那么线程B在tryAcquire()什么都不执行,并返回false,因为外面有一个!非,所以&&会继续向有执行,也就是会执行acquireQueued(addWaiter(Node.EXCLUSIVE), arg)
⑤addWaiter()

传入Node模式为EXCLUSIVE,排他类型
1 | private Node addWaiter(Node mode) { |
⑥enq()
进行enq将线程B入队

上来看到是一个自旋for (;;)
1 | private Node enq(final Node node) { |
- compareAndSetHead
![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Oxno2o4m-1641015862589)(../AppData/Roaming/Typora/typora-user-images/image-20220101121718771.png)]](https://img-blog.csdnimg.cn/00ea3c6d64b349e6bcfd6960f4d52602.png)
CAS操作,将当前队列同步器的头节点内存偏移量headOffset,预期是null,设置为上面new Node傀儡节点空Node。
- 此时全局状态图
![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-uFJCaEiI-1641015862590)(../AppData/Roaming/Typora/typora-user-images/image-20220101122415152.png)]](https://img-blog.csdnimg.cn/a5d21cf8c882469d9c4c0b122a8485fb.png?x-oss-process=image/watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA6Zi_5piM5Zac5qyi5ZCD6buE5qGD,size_16,color_FFFFFF,t_70,g_se,x_16)
![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Zb2q2t6J-1641015862591)(../AppData/Roaming/Typora/typora-user-images/image-20220101122516482.png)]](https://img-blog.csdnimg.cn/48e97506664545eaa6f18c66148b954a.png?x-oss-process=image/watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA6Zi_5piM5Zac5qyi5ZCD6buE5qGD,size_11,color_FFFFFF,t_70,g_se,x_16)
经过这里给AQS同步队列初始化了一个空Node/傀儡节点,因为这里是自旋的for (;;),所以线程B还会再循环再执行。
![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-NOt3mGiG-1641015862591)(../AppData/Roaming/Typora/typora-user-images/image-20220101122614536.png)]](https://img-blog.csdnimg.cn/d4bb361030284a78a5418dc766d5296a.png?x-oss-process=image/watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA6Zi_5piM5Zac5qyi5ZCD6buE5qGD,size_11,color_FFFFFF,t_70,g_se,x_16)
![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-hEMwiI6E-1641015862592)(../AppData/Roaming/Typora/typora-user-images/image-20220101122822230.png)]](https://img-blog.csdnimg.cn/95d99fbc6757476ab33220eb307bf09a.png?x-oss-process=image/watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA6Zi_5piM5Zac5qyi5ZCD6buE5qGD,size_16,color_FFFFFF,t_70,g_se,x_16)
1 | private Node enq(final Node node) { |
- 以上队列状态图如下
![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ikkXOQvG-1641015862593)(../AppData/Roaming/Typora/typora-user-images/image-20220101123502993.png)]](https://img-blog.csdnimg.cn/947b9345b7464f9992dd7f4838ffb801.png?x-oss-process=image/watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA6Zi_5piM5Zac5qyi5ZCD6buE5qGD,size_20,color_FFFFFF,t_70,g_se,x_16)
执行完enq(),就会返回线程B的node节点地址

那么接下来就会执行acquireQueued(),他传入的参数1为返回的线程B的node节点,和上面传下来的arg=1的参数。
⑦acquireQueued()
acquireQueued最为关键,就是将线程B抢不到锁后阻塞挂起
![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-GlYJP9Il-1641015862596)(../AppData/Roaming/Typora/typora-user-images/image-20220101123734881.png)]](https://img-blog.csdnimg.cn/bd82fbe6e71f49568b4e48eccf649aa2.png?x-oss-process=image/watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA6Zi_5piM5Zac5qyi5ZCD6buE5qGD,size_14,color_FFFFFF,t_70,g_se,x_16)
![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-5yUJKBD5-1641015862597)(../AppData/Roaming/Typora/typora-user-images/image-20220101124021578.png)]](https://img-blog.csdnimg.cn/560dc72d0e3e4b66b122b1b07cbdfa33.png?x-oss-process=image/watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA6Zi_5piM5Zac5qyi5ZCD6buE5qGD,size_14,color_FFFFFF,t_70,g_se,x_16)
1 | final boolean acquireQueued(final Node node, int arg) { |
- shouldParkAfterFailedAcquire
![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ScG59of6-1641015862598)(../AppData/Roaming/Typora/typora-user-images/image-20220101124150093.png)]](https://img-blog.csdnimg.cn/a6bbddc6ada64d2aaea8911b7d9ede2b.png?x-oss-process=image/watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA6Zi_5piM5Zac5qyi5ZCD6buE5qGD,size_18,color_FFFFFF,t_70,g_se,x_16)
![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-jQXVR61F-1641015862600)(../AppData/Roaming/Typora/typora-user-images/image-20220101124425111.png)]](https://img-blog.csdnimg.cn/be25212cbdb54ac38f741f5fad79fd08.png?x-oss-process=image/watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA6Zi_5piM5Zac5qyi5ZCD6buE5qGD,size_9,color_FFFFFF,t_70,g_se,x_16)
1 | private static boolean shouldParkAfterFailedAcquire(Node pred, Node node) { |
![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-S6BfJu0A-1641015862600)(../AppData/Roaming/Typora/typora-user-images/image-20220101124705851.png)]](https://img-blog.csdnimg.cn/fdfc880433f841b088e201e9d93e9898.png)
因为这里是自旋的死循环,所以还会再次进入执行。
![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-RKEHuYGK-1641015862601)(../AppData/Roaming/Typora/typora-user-images/image-20220101124719956.png)]](https://img-blog.csdnimg.cn/f1952a6c6bfa4fe38cf7de67c74ca0ab.png?x-oss-process=image/watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA6Zi_5piM5Zac5qyi5ZCD6buE5qGD,size_13,color_FFFFFF,t_70,g_se,x_16)
1 | final boolean acquireQueued(final Node node, int arg) { |
- 全局状态图
![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-snSJ1hEF-1641015862603)(../AppData/Roaming/Typora/typora-user-images/image-20220101125100609.png)]](https://img-blog.csdnimg.cn/6aaa82552762492581794fb13274ac10.png?x-oss-process=image/watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA6Zi_5piM5Zac5qyi5ZCD6buE5qGD,size_17,color_FFFFFF,t_70,g_se,x_16)
因为我们在shouldParkAfterFailedAcquire给p节点,也就是傀儡节点设置了他的waitState为Node.SIGNAL,也就是-1
![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-MwRT0FxR-1641015862605)(../AppData/Roaming/Typora/typora-user-images/image-20220101125157406.png)]](https://img-blog.csdnimg.cn/cf136fe697a04e48be2568d0b805100e.png?x-oss-process=image/watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA6Zi_5piM5Zac5qyi5ZCD6buE5qGD,size_20,color_FFFFFF,t_70,g_se,x_16)
第二次进入再次判断傀儡节点的waitStatus,因为上面设置为了-1,所以这次就会返回了true。那么接下来就会执行parkAndCheckInterrupt
![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-PDWdgbcj-1641015862608)(../AppData/Roaming/Typora/typora-user-images/image-20220101125242797.png)]](https://img-blog.csdnimg.cn/add2fe8127a2436984d97095421cd345.png)
- parkAndCheckInterrupt()
![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-kZ2JCil2-1641015862610)(../AppData/Roaming/Typora/typora-user-images/image-20220101125500624.png)]](https://img-blog.csdnimg.cn/ccf65e84ff86421fb946075a85edea09.png)
出现了!!!这里就是让线程B阻塞的罪魁祸首,LockSupport的park,这个this就是线程B。那么这里线程B就需要有人执行LockSupport.unpark(线程B)来唤醒他,不然他就会永远被阻塞挂起。
- 全局状态图
![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-uL26Aaq5-1641015862612)(../AppData/Roaming/Typora/typora-user-images/image-20220101125621559.png)]](https://img-blog.csdnimg.cn/16f1b28d810e4db8be9586828f1340df.png?x-oss-process=image/watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA6Zi_5piM5Zac5qyi5ZCD6buE5qGD,size_20,color_FFFFFF,t_70,g_se,x_16)
接下来就是等待持有资源的线程A执行unlock()方法了
3、线程A放弃锁
![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-LYe5TRKU-1641015862616)(../AppData/Roaming/Typora/typora-user-images/image-20220101125638116.png)]](https://img-blog.csdnimg.cn/df634261a1b7425caffe35d4c61f7738.png?x-oss-process=image/watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA6Zi_5piM5Zac5qyi5ZCD6buE5qGD,size_15,color_FFFFFF,t_70,g_se,x_16)
线程A执行玩逻辑之后,最终finally就会执行lock.unlock(),进行解锁,放弃锁资源
![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-DOe6Mhds-1641015862617)(../AppData/Roaming/Typora/typora-user-images/image-20220101125718552.png)]](https://img-blog.csdnimg.cn/5ebbe05fab7644e1a06bbcfd1774463a.png)
这里也能看出,ReentrantLock的unlock方法,依然是调用sync的release方法
![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-haWJsKSG-1641015862619)(../AppData/Roaming/Typora/typora-user-images/image-20220101125815616.png)]](https://img-blog.csdnimg.cn/72d9a18da33149f18feb4e1e4e1c2c22.png?x-oss-process=image/watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA6Zi_5piM5Zac5qyi5ZCD6buE5qGD,size_10,color_FFFFFF,t_70,g_se,x_16)
会看到这里他会先进入if,去执行tryRelease,同样,这个tryRelease执行的必然是实现类的方法,也就是Sync的tryRelease,模版设计模式
①tryRelease
![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-huEF9BgH-1641015862620)(../AppData/Roaming/Typora/typora-user-images/image-20220101125945274.png)]](https://img-blog.csdnimg.cn/93dad535cbc14e91a74719aeccc556a3.png?x-oss-process=image/watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA6Zi_5piM5Zac5qyi5ZCD6buE5qGD,size_14,color_FFFFFF,t_70,g_se,x_16)
1 | protected final boolean tryRelease(int releases) { |
- 全局状态图

1 | public final boolean release(int arg) { |
②unparkSuccessor
这个方法会唤醒,上面阻塞的线程B
![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-T4EcxA5B-1641015862624)(../AppData/Roaming/Typora/typora-user-images/image-20220101130501527.png)]](https://img-blog.csdnimg.cn/c72602c812ef49a99b1380a644098d63.png?x-oss-process=image/watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA6Zi_5piM5Zac5qyi5ZCD6buE5qGD,size_15,color_FFFFFF,t_70,g_se,x_16)
1 | private void unparkSuccessor(Node node) { |
LockSupport.unpark(s.thread)为线程B唤醒,所以线程B就是开始执行。这里线程A的unlock()就执行完毕了
- 全局状态图

4、线程B被线程A唤醒,并尝试去再抢锁
线程B被线程A唤醒,并自旋死循环,再次强占锁资源
①acquireQueued
![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-mWAsNpcF-1641015862627)(../AppData/Roaming/Typora/typora-user-images/image-20220101132117310.png)]](https://img-blog.csdnimg.cn/3d54b561cf0c4a76a9b31d04547081e5.png?x-oss-process=image/watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA6Zi_5piM5Zac5qyi5ZCD6buE5qGD,size_14,color_FFFFFF,t_70,g_se,x_16)
1 | final boolean acquireQueued(final Node node, long arg) { |
- tryAcquire()
同样是模版设计模式,会去执行Sync的实现
![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-9lIRQr9t-1641015862629)(../AppData/Roaming/Typora/typora-user-images/image-20220101132530000.png)]](https://img-blog.csdnimg.cn/09eed507582442ff8975521f44e6b9d3.png)
- nonfairTryAcquire()
1 | final boolean nonfairTryAcquire(int acquires) { |
- setHead()
设置线程B的Node为头节点,设置线程B的Node中的线程为null,线程B的Node的前节点为null
![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-iHeavONT-1641015862631)(../AppData/Roaming/Typora/typora-user-images/image-20220101133223868.png)]](https://img-blog.csdnimg.cn/bab24b363f41416ab8ef4c4107b76db4.png)
- 全局状态图
![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-BIEWlNsI-1641015862643)(../AppData/Roaming/Typora/typora-user-images/image-20220101133531677.png)]](https://img-blog.csdnimg.cn/15425ceaeac5479ebceec0f7f96913d2.png?x-oss-process=image/watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA6Zi_5piM5Zac5qyi5ZCD6buE5qGD,size_20,color_FFFFFF,t_70,g_se,x_16)
以此循环,如果有别的线程加入队列也是维持以上的流转管理操作。
四、结尾
以上就满足了AQS的管理流转,通过资源变量State+AQS的同步管理队列,实现了线程强占资源的管理。
用资源变量State来控制当前资源是否被占用,0为未占用状态,大于0为被占用情况。
抢不到资源的线程会被AQS维护管理在虚拟的同步管理队列,通过LockSupprot进行线程的唤醒和阻塞。
现在再细品一开始的话:
通过一个资源state,来表示锁的状态。0是自由状态,大于0代表被占用。抢不到资源的线程,就放在FIFO队列中进行管理,争取下次再进行争取获取资源
以上就是这次的全部内容,感谢你能看到这里(๑ˉ∀ˉ๑)!!!