AQS

简介: 一、为什么需要AQS?以及AQS的作用和重要性?AQS(AbstractQueuedSynchronizer)的重要性AQS被用在ReentrantLock、ReentrantReadWriteLock、Semaphore、CountDownLatch、ThreadPoolExcutor的Worker中都有运用(JDK1.8)。AQS是这些类的底层原理,JUC包里很多重要的工具类背后都离不开AQS框架。

一、为什么需要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等方法。

目录
相关文章
|
7月前
|
安全 Java
【深入理解同步器AQS】
【深入理解同步器AQS】
|
7月前
|
人工智能 算法
同步器的介绍
一、同步器的基本原理 同步器是一种电子电路,用于同的电子信号进行同步。它的基本原理是根据输入信号的特征,通过适当的控制和调节,使输出信号与输入信号保持同步。同步器通常由触发器、计数器、时钟等组成,通过这些元件的协同工作,实现信号的同步和精确控制。 二、同步器的应用领域 同步器在各个领域都有广泛的应用。在通信领域,同步器用于确保数据传输的准确性和稳定性。在计算机领域,同步器用于控制和同步各个部件的工作,保证计算机系统的正常运行。在音视频领域,同步器用于音频和视频信号的同步播放,提供更好的观看和听觉体验。在工业自动化领域,同步器用于控制和同步各个机械设备的运行,提高生产效率和精确度。 三、同步器的
97 0
|
17天前
|
安全 Java
利用AQS(AbstractQueuedSynchronizer)实现一个线程同步器
利用AQS(AbstractQueuedSynchronizer)实现一个线程同步器
|
2月前
【1】请问什么是 AQS?
【1】请问什么是 AQS?
25 0
|
4月前
|
存储 设计模式 安全
理解 AQS 和 ReentrantLock
在多线程编程中,同步机制是确保线程安全的关键。AQS(AbstractQueuedSynchronizer)和ReentrantLock是Java中两种常见的同步机制,它们各自具有不同的特性和适用场景。了解和掌握这两种机制对于编写高效、安全的并发程序至关重要。这篇文章将带你取了解和掌握这两种机制!另外值得一提的是:公平锁的实现与非公平锁是很像的,只不过在获取锁时不会直接尝试使用CAS来获取锁。只有当队列没节点并且state为0时才会去获取锁,不然都会把当前线程放到队列中。
117 1
|
7月前
|
存储 Java 开发者
AbstractQueuedSynchronizer之AQS
AbstractQueuedSynchronizer之AQS
|
9月前
|
算法 Java
了解AQS
了解AQS
54 0
|
10月前
|
Java C++
什么是AQS?
AQS(AbstractQueuedSynchronizer)是Java中的一个同步器框架
377 1
|
11月前
|
计算机视觉
AQS
AQS
53 0
|
设计模式 安全 Java