AQS介绍

article/2025/10/7 17:27:25

目录

    • 1. AQS简介:
    • 2. AQS的原理:
    • 3. 和AQS相关的类:
    • AQS能干嘛:
    • AQS初步:
    • AQS内部体系架构:

1. AQS简介:

AQS是什么:

AQS全名:AbstractQueuedSynchronizer即抽象的队列同步器,这个类在java.util.concurrent.locks包下面。它实现了一个FIFO(FirstIn、FisrtOut先进先出)的队列。AQS底层实现的数据结构是一个双向链表

在这里插入图片描述

AQS抽象队列同步器:
抽象的队列同步器, 用来构建锁或者其他同步器组件的重量级基础框架及整个JUC体系的基石,通过内置的FIFO队列来完成资源获取线程的排队工作,并通过一个int类型变量表示持有锁的状态;

  1. 抽象: 符合模板设计模式,作为核心父类给子类继承
  2. 队列: 对抢占不到锁的管理
  3. 同步器: 队列的排队的线程进行管理

AQS作用:加锁会导致阻塞,有阻塞就会排队,实现排队必然需要有某种形式的队列来进行管理:

  • AQS是一个用来构建锁和同步器的框架,使用AQS能简单且高效地构造出应用广泛的大量的同步器,比如我们提到的ReentrantLock,Semaphore,CountDownLatch,其他的诸如ReentrantReadWriteLock,SynchronousQueue,LinkedBlockingQueue等,FutureTask等等皆是基于AQS的。当然,我们自己也能利用AQS非常轻松容易地构造出符合我们自己需求的同步器

    LinkedBlockingQueue是线程安全的,那就要解决互斥和同步的问题,这一点我们可以通过Java中提供的锁来解决。Java中锁分两大类,一类是synchronized实现的隐式锁,另一类是并发编程大师Doug Lea基于AQS实现的锁。由于LinkedBlockingQueue是Doug Lea所编写的类,因此LinkedBlockingQueue底层使用的是AQS类型的锁,即:ReentrantLock。

  • ReentrantLock底层使用了CAS+AQS队列实现,所以我们基于ReentrantLock的一些线程安全的阻塞队列(如ArrayBlockingQueue ,LinkedBlockingQueue ,PriorityBlockingQueue ,DelayQueue,SynchronousQueue,LinkedBlockingDeque)的最底层都是AQS;

  • 是用来构建锁或者其它同步器组件的重量级基础框架及整个JUC体系的基石, 通过内置的FIFO队列来完成资源获取线程的排队工作,并通过一个int类变量state 表示持有锁的状态;

在这里插入图片描述

2. AQS的原理:

AQS核心思想是:

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

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

AQS为实现阻塞锁,依赖先进先出的一个等待,依靠一个原子int值的state来表示状态,通过占用和释放方法,改变状态值AQS使用一个volatile的int类型的成员变量来表示同步状态,通过内置的FIFO队列来表示完成获取资源的排队工作将每条要去抢占资源的线程封装成一个Node节点来实现锁的分配,通过CAS完成对State值得修改;

看个AQS(AbstractQueuedSynchronizer)原理图:AQS本质是一个状态变量+队列

在这里插入图片描述

AQS使用一个int成员变量state来表示同步状态(state为0表示没有被占用,大于0表示被占用),通过内置的FIFO队列来完成获取资源线程的排队工作。AQS使用CAS对该同步状态进行原子操作实现对其值的修改。

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

3. 和AQS相关的类:

ReentrantLock底层是Sync类–>Sync类继承了AbstractQueuedSynchronizer:

在这里插入图片描述

CountDownLatch底层也是Sync类–>Sync继承了AbstractQueuedSynchronizer:

private static final class Sync extends AbstractQueuedSynchronizer

在这里插入图片描述

可重入的读写锁:
ReentrantReadWriteLock 中也有一个内部类Sync–>Sync类继承了 AbstractQueuedSynchronizer:

在这里插入图片描述

信号灯类:Semaphore中的内部类Sync extends AbstractQueuedSynchronizer
在这里插入图片描述

总结:和AQS有关的类:
在这里插入图片描述

理解锁和同步器的关系:

锁,就是API方面写好的现成的锁,如ReentrantReadWriteLock,ReentrantLock等,我们直接拿来用。

①锁,面向锁的使用者:定义了程序员和锁交互的使用层API,隐藏了实现细节,你调用即可。
②同步器,面向锁的实现者:比如Java并发大神Douglee,提出统一规 范并简化了锁的实现,屏蔽了同步状态管理、阻塞线程排队和通知、唤醒机制等。

在这里插入图片描述

AQS能干嘛:

加锁会导致阻塞,有阻塞就需要排队,实现排队必然需要有某种形式的队列来进行管理

1.抢到资源的线程直接使用办理业务,抢占不到资源的线程的必然涉及一种排队等候机制,抢占资源失败的线程继续去等待(类似办理窗口都满了,暂时没有受理窗口的顾客只能去候客区排队等候),仍然保留获取锁的可能且获取锁流程仍在继续(候客区的顾客也在等着叫号,轮到了再去受理窗口办理业务).

2.既然说到了排队等候机制,那么就一定会有某种队列形成,这样的队列是什么数据结构呢?

3.如果共享资源被占用,就需要一定的阻塞等待唤醒机制来保证锁分配。这个机制主要用的是CLH队列的变体实现的,将暂时获取不到锁的线程加入到队列中,这个队列就是AQS的抽象表现。它将请求共享资源的线程封装成队列的结点(Node) ,通过CAS、自旋以及LockSuport.park()的方式,维护state变量的状态,使并发达到同步的效果。

在这里插入图片描述

AQS初步:

在这里插入图片描述

AQS使用一个volatile的int类型的成员变量state来表示同步状态,通过内置的 FIFO队列来完成资源获取的排队工作将每条要去抢占资源的线程封装成 一个Node节点来实现锁的分配,通过CAS完成对state值的修改

在这里插入图片描述
hashMap中的k,v键值对 本质是放在一个Node<k,v>节点中的,而不是直接放进Map中的:
同理,我们的AQS中同样也有一个内部类节点Node<Thread>,用于存放线程,此时Node<Thread>是一个载体:AQS中装的是Node:
在这里插入图片描述

在这里插入图片描述

AQS内部体系架构:

看源码可知道:
可重入锁类ReentrantLock 实现了 Lock接口;
可重入锁类ReentrantLock 中 有三个内部类:Sync+NonFairSync+FairSync;
Sync内部类 又是其他 两个内部类(NonFairSync+FairSync)的父类;
Sync内部类 又是一个单独抽象类AbstractQueuedSynchronizer的子类;

在这里插入图片描述

1.AQS自身:

①AQS的int变量state:
AQS的同步状态state成员变量,可以理解为银行办理业务的受理窗口状态,零就是没人(锁是空闲的),自由状态可以办理。大于等于1(锁被占用),有人占用窗口,就需要去排队等待。

/*** The synchronization state.*/
private volatile int state;

②AQS的CLH队列:
CLH队列(三个大牛的名字组成),为一个双向队列。可以理解为银行的候客区

小总结:有阻塞就需要排队,实现排队必然需要队列。(state变量+CLH双端Node队列)
在这里插入图片描述

在这里插入图片描述

2.内部类Node(Node类在AQS类内部)

①Node的int变量waitStatus:
Node的等待状态waitStatus。可以理解为队列中每个排队的个体就是一个Node,这个变量就是等候区其它顾客(其它线程)的等待状态。

在这里插入图片描述

②Node此类的讲解:
在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

最终的方法落地到这里两个方法:
在这里插入图片描述

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

代码演示:
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

总结:

在这里插入图片描述

释放锁源码:

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述


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

相关文章

如何理解AQS

AQS核心数据结构 AQS内部主要维护了一个FIFO&#xff08;先进先出&#xff09;的双向链表。 AQS数据结构原理 AQS内部维护的双向链表中的各个节点分别指向直接的前驱节点和直接的后续节点。所以&#xff0c;在AQS内部维护的双向链表可以从其中的任意一个节点遍历前驱结点和后…

AQS解析

Java中的大部分同步类&#xff08;Lock、Semaphore、ReentrantLock等&#xff09;都是基于AbstractQueuedSynchronizer&#xff08;简称为AQS&#xff09;实现的。AQS是一种提供了原子式管理同步状态、阻塞和唤醒线程功能以及队列模型的简单框架。本文会从应用层逐渐深入到原理…

AQS机制

1、什么是AQS&#xff1f; AQS是抽象同步队列&#xff0c;基于CAS和LockSupport实现&#xff0c;通过资源状态state和AQS的同步队列实现线程抢占资源的管理。 2、获取资源 线程进来先获取资源&#xff0c;如果失败会重试一次&#xff0c;再次失败会将当前线程存放至…

AQS原理

AQS是一个构建锁和同步器的并发框架&#xff0c;是AbstractQueuedSynchronizer的缩写&#xff0c;常见AQS实现的同步器框架有ReentrantLock,Semaphore,Latch,Barrier,BlockingQueue等多种多线程访问共享资源的同步器框架&#xff0c;AQS是一种依赖状态&#xff08;state&#x…

AQS

AQS 简介AQS原理分析AQS原理概览AQS对资源的共享方式AQS低层使用了模板方法模式 AQS组件总结 简介 AQS的全称为&#xff08;AbstractQueuedSynchronizer&#xff09;&#xff0c;这个类在java.util.concurrent.locks包下面。 AQS是一个用来构建锁和同步器的框架&#xff0c;使…

Java技术之AQS详解

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

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

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

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

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

AQS详解

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

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

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

什么是AQS

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

泛函分析之变分法

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

变分法是最优控制问题的三大基石之一&#xff0c;下面讨论一些变分法的常用理论。 1. 性能指标泛函 无约束最优控制问题&#xff0c;若固定起止时间&#xff0c;两端状态固定&#xff0c;即 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…