AQS

article/2025/10/7 18:59:46

AQS

  • 简介
  • AQS原理分析
    • AQS原理概览
    • AQS对资源的共享方式
    • AQS低层使用了模板方法模式
  • AQS组件总结

简介

AQS的全称为(AbstractQueuedSynchronizer),这个类在java.util.concurrent.locks包下面。
在这里插入图片描述
AQS是一个用来构建锁和同步器的框架,使用AQS能简单且高效地构造出应用广泛的大量的同步器,比如ReentrantLock,Semaphore,其他的诸如ReentrantReadWriteLock,SynchronousQueue,FutureTask等等皆是基于AQS的。当然,我们自己也能利用AQS非常轻松容易地构造出符合我们自己需求的同步器。

AQS原理分析

AQS原理概览

AQS核心思想是:如果被请求的共享资源空闲,则将当前请求资源的线程设置为有效的工作线程,并且将共享资源设置为锁定状态。如果被请求的共享资源被占用,那么就需要一套线程阻塞等待以及被唤醒时锁分配的机制,这个机制AQS是用CLH队列锁实现的,即将暂时获取不到锁的线程加入到队列中。

CLH(Craig,Landin,and Hagersten)队列是一个虚拟的双向队列(虚拟的双向队列即不存在队列实例,仅存在结点之间的关联关系)。
AQS是将每条请求共享资源的线程封装成一个CLH锁队列的一个结点(Node)来实现锁的分配。

AQS(AbstractQueuedSynchronizer)原理图:
在这里插入图片描述
AQS使用一个int成员变量来表示同步状态,通过内置的FIFO队列来完成获取资源线程的排队工作。AQS使用CAS对该同步状态进行原子操作实现对其值的修改。

private volatile int state;//共享变量,使用volatile修饰保证线程可见性

状态信息通过protected类型的getState,setState,compareAndSetState进行操作

//返回同步状态的当前值
protected final int getState() {  return state;
}// 设置同步状态的值
protected final void setState(int newState) { state = newState;
}//原子地(CAS操作)将同步状态值设置为给定值update如果当前同步状态的值等于expect(期望值)
protected final boolean compareAndSetState(int expect, int update) {return unsafe.compareAndSwapInt(this, stateOffset, expect, update);
}

AQS对资源的共享方式

AQS定义两种资源共享方式

Exclusive(独占):只有一个线程能执行,如ReentrantLock。又可分为公平锁和非公平锁:
公平锁:按照线程在队列中的排队顺序,先到者先拿到锁
非公平锁:当线程要获取锁时,无视队列顺序直接去抢锁,谁抢到就是谁的

Share(共享):多个线程可同时执行,如Semaphore/CountDownLatch。Semaphore、CountDownLatch、 CyclicBarrier、ReadWriteLock 我们都会在后面讲到。
ReentrantReadWriteLock 可以看成是组合式,因为ReentrantReadWriteLock也就是读写锁允许多个线程同时对某一资源进行读。

不同的自定义同步器争用共享资源的方式也不同。自定义同步器在实现时只需要实现共享资源 state 的获取与释放方式即可,至于具体线程等待队列的维护(如获取资源失败入队/唤醒出队等),AQS已经在顶层实现好了。

AQS低层使用了模板方法模式

同步器的设计是基于模板方法模式的,如果需要自定义同步器一般的方式是这样(模板方法模式很经典的一个应用):

使用者继承AbstractQueuedSynchronizer并重写指定的方法。(这些重写方法很简单,无非是对于共享资源state的获取和释放)
将AQS组合在自定义同步组件的实现中,并调用其模板方法,而这些模板方法会调用使用者重写的方法。
这和我们以往通过实现接口的方式有很大区别,这是模板方法模式很经典的一个运用。

AQS使用了模板方法模式,自定义同步器时需要重写下面几个AQS提供的模板方法:

isHeldExclusively()//该线程是否正在独占资源。只有用到condition才需要去实现它。
tryAcquire(int)//独占方式。尝试获取资源,成功则返回true,失败则返回false。
tryRelease(int)//独占方式。尝试释放资源,成功则返回true,失败则返回false。
tryAcquireShared(int)//共享方式。尝试获取资源。负数表示失败;0表示成功,但没有剩余可用资源;正数表示成功,且有剩余资源。
tryReleaseShared(int)//共享方式。尝试释放资源,成功则返回true,失败则返回false。

默认情况下,每个方法都抛出 UnsupportedOperationException。 这些方法的实现必须是内部线程安全的,并且通常应该简短而不是阻塞。AQS类中的其他方法都是final ,所以无法被其他类使用,只有这几个方法可以被其他类使用。

以ReentrantLock为例,state初始化为0,表示未锁定状态。A线程lock()时,会调用tryAcquire()独占该锁并将state+1。此后,其他线程再tryAcquire()时就会失败,直到A线程unlock()到state=0(即释放锁)为止,其它线程才有机会获取该锁。当然,释放锁之前,A线程自己是可以重复获取此锁的(state会累加),这就是可重入的概念。但要注意,获取多少次就要释放多么次,这样才能保证state是能回到零态的。

再以CountDownLatch以例,任务分为N个子线程去执行,state也初始化为N(注意N要与线程个数一致)。这N个子线程是并行执行的,每个子线程执行完后countDown()一次,state会CAS(Compare and Swap)减1。等到所有子线程都执行完后(即state=0),会unpark()主调用线程,然后主调用线程就会从await()函数返回,继续后余动作。

一般来说,自定义同步器要么是独占方法,要么是共享方式,他们也只需实现tryAcquire-tryRelease、tryAcquireShared-tryReleaseShared中的一种即可。但AQS也支持自定义同步器同时实现独占和共享两种方式,如ReentrantReadWriteLock。

AQS组件总结

  • Semaphore(信号量)-允许多个线程同时访问: synchronized 和 ReentrantLock 都是一次只允许一个线程访问某个资源,Semaphore(信号量)可以指定多个线程同时访问某个资源。
  • CountDownLatch (倒计时器): CountDownLatch是一个同步工具类,用来协调多个线程之间的同步。这个工具通常用来控制线程等待,它可以让某一个线程等待直到倒计时结束,再开始执行。
  • CyclicBarrier(循环栅栏): CyclicBarrier 和 CountDownLatch 非常类似,它也可以实现线程间的技术等待,但是它的功能比 CountDownLatch 更加复杂和强大。主要应用场景和 CountDownLatch 类似。CyclicBarrier 的字面意思是可循环使用(Cyclic)的屏障(Barrier)。它要做的事情是,让一组线程到达一个屏障(也可以叫同步点)时被阻塞,直到最后一个线程到达屏障时,屏障才会开门,所有被屏障拦截的线程才会继续干活。CyclicBarrier默认的构造方法是 CyclicBarrier(int parties),其参数表示屏障拦截的线程数量,每个线程调用await()方法告诉 CyclicBarrier 我已经到达了屏障,然后当前线程被阻塞。

http://chatgpt.dhexx.cn/article/g2ItvIAJ.shtml

相关文章

Java技术之AQS详解

AbstractQueuedSynchronizer 简写为AQS,抽象队列同步器。它是一个用于构建锁和同步器的框架,许多同步器都可以通过AQS很容易并且高效的构造出来,以下都是通过AQS构造出来的:ReentrantLock, ReentrantReadWriteLock A…

(面经总结)一篇文章带你完整复习 Java 中的 AQS

文章目录 一、什么是AQS二、AQS的原理三、state:状态四、AQS共享资源的方式:独占式和共享式一、什么是AQS AQS(Abstract Queued Synchronizer)是一个抽象的队列同步器,通过维护一个共享资源状态(Volatile Int State)和一个先进先出(FIFO)的线程等待队列来实现一个多线…

AQS详细大分解,彻底弄懂AQS

AQS深入分析总结 AQS 很久之前便写了这篇文章,一直没有时间发出来,文章如果有写的不好的地方,欢迎大家能够指正,下面开始详细分析介绍,希望大家能够耐心读下去,肯定会受益匪浅的,AQS是Java JU…

AQS详解

AQS是AbstractQueuedSynchronizer的简称。AQS提供了一种实现阻塞锁和一系列依赖FIFO等待队列的同步器的框架,如下图所示。AQS为一系列同步器依赖于一个单独的原子变量(state)的同步器提供了一个非常有用的基础。子类们必须定义改变state变量的…

一文让你彻底搞懂AQS(通俗易懂的AQS)

一文让你彻底搞懂AQS(通俗易懂的AQS) 一、什么是AQS AQS是一个用来构建锁和同步器的框架,使用AQS能简单且高效地构造出应用广泛的大量的同步器,比如我们提到的ReentrantLock,Semaphore,其他的诸如ReentrantReadWriteLock&#x…

什么是AQS

AQS ( Abstract Queued Synchronizer )是一个抽象的队列同步器,通过维护一个共享资源状态( Volatile Int State )和一个先进先出( FIFO )的线程等待队列来实现一个多线程访问共享资源的同步框架。 一、AQS…

泛函分析之变分法

泛函数 以上截图来自于《变分法简介Part 1.(Calculus of Variations)》 变分法 研究泛函极值的方法就是所谓变分法。 以上截图来自于《最速降线的数学模型—变分法》 欧拉-拉格朗日方程

mathematica变分法和样条插值求解最小旋转曲面

mathematica求解最小面积旋转曲面 做你没做过的事叫成长,做你不愿做做的事叫改变,做你不敢做的事叫突破。—— 巴菲特 问题描述: 在一条直线的同一侧有两个已知点,试找出一条连接这两点的曲线,使这条曲线绕直线旋转所…

变分法模型的运用:生产设备的最大经济效益

上一节介绍了 动态优化模型/ 变分法 的基本思想,本节将一个变分法的运用。 目录 1 问题分析与假设 2 模型构造 3 模型求解 变分法习题 某工厂购买了一台新设备投入到生产中。一方面该设备随着运行时间的推…

简述变分法在泛函极值问题中的应用

此文主要有两部分内容,一部分是泛函的一些基本概念;第二部分是变分法在研究泛函极值问题中的应用。 第一部分 泛函 泛函是函数概念的一种扩充,函数描述的是从数到数的对应关系,从自变量到因变量的一种对应关系;而泛函…

变分法(欧拉 - 拉格朗日)和梯度下降求泛函最优解

泛函的简单理解: 是的变量, 这样的就叫泛函 . 加个积分,这样的就叫积分泛函 . 欧拉 - 拉格朗日 (E - L) 公式: 定义一个能量泛函如下: 我们的目的是找到能使 取到极值的时候 的取值,所以我们就假设 就…

第二章-最优控制中的变分法(经典变分法或古典变分法)1

是《最优控制理论与应用(邵克勇,王婷婷,宋金波)》的读书笔记,相比于其他的书,选择这本书的理由是页数少,能读完。解学书的《最优控制理论与应用》看目录感觉很全,但是太厚了,感觉看不完。 虽然…

变分法理解1——泛函简介

变分法是处理泛函的数学领域,和处理函数的传统微积分相对。 对泛函求极值的问题称为变分问题,使泛函取极值的函数称为变分问题的解,也称为极值函数。 传统的微积分中的一个常见的问题是找到一个 x x x 值使得 y ( x ) y(x) y(x) 取得最大值…

变分法证明两点之间线段最短

传送门https://zhuanlan.zhihu.com/yueaptx 变分法简介Part 1.(Calculus of Variations) Dr.Stein 计算力学 ​关注他 283 人赞了该文章 泛函数 (Functionals) 简而言之,泛函数是函数的函数,即它的输入是函数,输出…

最优控制理论 一、变分法和泛函极值问题

变分法是最优控制问题的三大基石之一,下面讨论一些变分法的常用理论。 1. 性能指标泛函 无约束最优控制问题,若固定起止时间,两端状态固定,即 x ( 0 ) x 0 , x ( t f ) x f , t ∈ [ 0 , t f ] x(0)x_0, x(t_f)x_f, t\in[0,t…

[变分法介绍]优美的旋轮线:最速下降线问题,通过费马光学原理的初等证明

[变分法介绍]优美的旋轮线:最速下降线问题,通过费马光学原理的初等证明 变分法 费马光学原理最速下降线问题旋轮线旋轮线最速下降性质的证明一些旋轮线及变形参考书目:1696年约翰伯努利在写给他哥哥雅克布伯努利的一封公开信中提出了如下的“捷线”问题:设想一个质点沿连接…

深入浅出解析变分法——一种常用的数学方法

前言:笔者从事图像处理行业,总是接触到变分法这个概念,一直没有很深入的去理解这个概念,同时我看其他大佬的博文也比较糊涂,因此最近花了一些时间好好梳理了这部分数学知识。文章共3部分,主要是对变分法的解…

变分法:在图像处理中的应用(一)

前言 最近学习稠密重建的相关知识,发现变分法通常作为一个平滑的正则项出现在残差平方和的损失函数中。而图像处理中又经常出现这类最小损失函数的优化问题,如图像分割、稠密光流、稠密重建等等,这些优化问题中都有可能涉及到变分法。因此&am…

电磁仿真原理——3. 变分法(Variationl Methods)

目录 引言线性空间的算子问题变分的计算问题欧拉公式 构造泛函的方法利用分部积分构造利用标准变分原理构造 瑞利一里茨法加权留数法本征问题变分的实际应用 引言 由于课程后面重点的矩量法和有限元法都是基于变分法进行的,变分法是它们的数学基础,实际…

泛函极值问题与变分法

泛函与泛函极值问题 平面内两点A,B,连接两点之间的曲线有很多种方式。分别用函数 f i ( x ) f_{i}(x) fi​(x)来表示。对于给定的曲线 f i ( x ) f_{i}(x) fi​(x), 那么两点之间连线的长度可以表示为 J ( f i ( x ) ) ∫ A B 1 f i ′ ( x ) 2 d x J…