当前位置:   article > 正文

AQS_aqs的state

aqs的state

一、为什么需要AQS?以及AQS的作用和重要性?

AQS(AbstractQueuedSynchronizer)的重要性

AQS被用在ReentrantLock、ReentrantReadWriteLock、Semaphore、CountDownLatch、ThreadPoolExcutor的Worker中都有运用(JDK1.8)。AQS是这些类的底层原理,JUC包里很多重要的工具类背后都离不开AQS框架。

目的是为了理解器背后的原理,学习设计思想。

我们先从宏观的角度去解读AQS,比如为什么需要AQS?AQS有什么作用。

AQS 作用是一个用于构建锁、同步器等线程协作工具类的框架,利用AQS可以很方便的实现线程协作工具类。而且AQS被广泛应用在JUC包中

很多用于线程协作的工具类就都可以很方便的被写出来

可以让更上层的开发极大的减少工作量,避免重复早轮子。

避免了上层因处理不当而导致的线程安全问题,AQS把这些都做好了。

二、AQS内部原理解析

AQS最核心的三个部分作为重点:

状态、队列(FIFO队列)、期望协作工具类去实现的获取/释放等重要方法

1、state状态

private volatile int state;

state根据具体实现类的作用不同而表示不同的含义。

例如:在信号量里面,state表示的是剩余许可证的数量

如果我们最开始把state设置为10,这就代表许可证初始一共有10个,然后当某一个线程取走一个许可证之后,这个state就会变为9,所以信号量的state相当于是一个内部计数器。

例如:在CountDownLatch工具类里面,state表示的是需要“倒数”的数量

一开始我们假设把它设置为5,当每次调用CountDown方法时,state就会减1,一致减到0的时候就代表这个门闩被放开。

例如:state在ReentrantLock中的含义

在ReentrantLock中它表示的是锁的占有情况

最开始0,表示没有任何线程占有锁,如果state变成1,则就代表这个锁已经被某一个线程所持有了。

为什么会往上加呢?

因为ReentrantLock是可重入的,同一个线程不用释放锁,可以再次拥有这把锁就叫重入,如果这个锁被同一个线程多次获取,那么state就会逐渐的往上加,state的值标识重入的次数。

state状态

state修改,因为state是会被多个线程共享的,会被并发地修改,所以去修改的state的方法都必须要保证state是线程安全的,可是state本身它仅仅被volatile修饰的,volatile本身并不足以保证线程安全。volatile的作用,当基本类型的变量进行直接赋值时,如果加了volatile就可以保证它的线程安全,这个就是setstate方法,线程安全的原因。

在AQS中有一个属性是state,它会被并发修改,它代表当前工具类的某种状态,在不同类总代表不同的含义。

2、FIFO队列

FIFO队列,即先进先出队列

这个队列最主要的作用是存储等待的线程

假设很多线程都想要同时强锁,那么大部分的线程是抢不到的,就需要有一个对了来存放、管理它们,所以AQS的一大功能就是充当线程的“排队管理器”。

这个队列是双向链表的形式,其数据结构看似简单,但是想要维护成一个线程安全的双向队列却非常复杂。

因为要考虑很多的线程并发问题。

3、获取/释放方法

获取和释放相关的重要方法,这些方法是协作工具类的逻辑的具体体现

需要每一个协作用具类自己去实现。所以在不同的工具类中,它们的实现和含义各不相同。

获取方法,获取操作通常会依赖state变量的值,根据state值不同,协作工具类也会有不同的逻辑

并且在获取的时候也会经常阻塞。

总结:

state 是一个数值,在不同的类中表示不同的含义,往往代表一种状态;

队列,该队列用来存放线程;

“获取、释放”的相关方法,需要利用AQS的工具类根据自己的逻辑去实现。

三、AQS在CountDownLatch类中的应用原理?

1、AQS用法

2、AQS在CountDownLatch的应用

3、总结

1、AQS用法,利用AQS类的主要步骤

1)新建一个自己的线程协作工具类

在内部写一个Sync类

该Sync类继承AbstractQueuedSynchronizer 即AQS。

2)想好设计的线程协作工具类的协作逻辑

在Sync类里根据是否是独占,来重写对应的方法

如果是独占,则重写tryAcquire和tryRelease等方法

如果是非独占,则重写tryAcquireShared和tryReleaseShared等方法

3)在自己的线程协作工具类中实现获取/释放的相关方法

并在里面调用AQS对应的方法

独占则调用acquire或release等方法

非独占则调用acquireShared或releaseShared 或acquireShareInterruptibly等方法。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/菜鸟追梦旅行/article/detail/149161
推荐阅读
  

闽ICP备14008679号