当前位置: 首页 > news >正文

java AQS

什么是AQS

AQS(AbstractQueuedSynchronizer,抽象队列同步器)是 Java 中并发控制的一种机制,位于 java.util.concurrent.locks 包下,它为构建锁、信号量等同步工具提供了一个框架。AQS 通过 队列 来管理多个线程之间的同步与竞争,利用 FIFO 队列 来顺序执行线程,并通过内部的状态变量(state)来控制资源的分配和访问。
在这里插入图片描述

为什么需要 AQS?

AQS 解决了 并发编程中线程同步和竞争 的一系列问题。具体来说,AQS 提供了一种高效、灵活的方式来管理线程的排队、同步和竞争,它的核心作用是通过维护一个 同步队列 和 状态变量 来协调多个线程对共享资源的访问。

AQS 的引入解决了以下问题:

线程排队管理:在高并发场景下,多个线程可能竞争同一个资源或锁。AQS 通过维护一个 FIFO 队列 来确保线程按照请求的顺序排队等待资源,避免了线程被无序唤醒或频繁切换造成的资源浪费。

锁的抽象:在 Java 中,锁机制如 ReentrantLock 和 Semaphore 等都依赖于 AQS 来实现。AQS 提供了一个通用的机制,让不同的锁机制可以复用相同的底层实现,而无需重复编写线程管理和同步控制代码。

线程阻塞和唤醒机制:AQS 通过内建的阻塞和唤醒机制,能够实现线程的高效挂起与唤醒。通过 ConditionObject 和 LockSupport,AQS 可以将线程挂起,避免不必要的 CPU 占用,直到条件满足时才唤醒。

非公平与公平锁:AQS 通过队列管理,可以方便地实现公平锁和非公平锁的不同策略。非公平锁会让新加入的线程有可能直接获取锁,而公平锁会按照队列的顺序逐一唤醒等待线程。

AQS 的核心机制以及底层原理

AQS 主要依赖以下几个关键组件来实现同步:

状态变量(state):AQS 通过 state 变量来表示同步器的当前状态。不同的同步器(如锁、信号量等)会根据自己的需求设定 state 的含义。例如,ReentrantLock 中的 state 表示当前锁是否被占用,state = 0 表示没有线程持有锁,state > 0 表示有线程持有锁。
在这里插入图片描述

双向队列:AQS 内部维护了一个 FIFO 队列(即 CLH 队列),用于管理等待获取资源的线程。线程在等待资源时会被加入到队列中,线程会按照队列的顺序获取资源。
在这里插入图片描述

线程阻塞与唤醒:AQS 提供了高效的线程阻塞与唤醒机制。线程在获取不到锁或资源时会被阻塞,直到资源可用或者条件满足时才会被唤醒。线程的挂起与唤醒通常通过 LockSupport.park() 和 LockSupport.unpark() 来实现。

总结

非公平锁:
使用ReentranLock加锁,以及其他自定义锁的时候,都是基于AQS实现的
当第一个线程获取锁的时候先判断state值,因为state值为0,所以直接获取锁,这时候另一个线程想获取lock锁,通过自旋和CAS判断state,如果state为0则获取锁,不是则加入双向队列,然后其他线程加入进行也是一样的,自旋CAS获取锁,这时候因为是ReentrantLock是非公平锁,也可以说AQS是非公平的,双向队列中的其他等待线程也在自旋+CAS获取锁,哪个抢到锁则哪个推出双向等待队列
公平锁:
如果修改为公平锁,则按队列顺序获取锁。例如有5个线程,后面的线程需要等待前面的释放锁之后在被唤醒(阻塞状态-》可执行状态)然后进行自旋+CAS获取锁

AQS的使用场景

自定义锁:
ReentrantLock:ReentrantLock 是一种可重入的互斥锁,它依赖于 AQS 来管理锁的获取和释放。AQS 提供了线程的排队、竞争和资源分配机制,使得 ReentrantLock 能够高效地管理锁的状态。

ReentrantReadWriteLock:ReentrantReadWriteLock 也使用 AQS 来实现读写锁。AQS 在这里管理读锁与写锁的状态以及线程的等待队列。

StampedLock:StampedLock 是 JDK 8 中引入的高级锁,它也依赖于 AQS 来实现与 ReentrantReadWriteLock 类似的读写锁功能。

任务协调和同步:
CountDownLatch:CountDownLatch 也是基于 AQS 实现的,它允许一个或多个线程等待其他线程完成某些操作之后再继续执行。它通过 AQS 的状态变量来控制计数器的减少和线程的阻塞与唤醒。

CyclicBarrier:CyclicBarrier 用于协调多个线程在某个点上同步,通过 AQS 的队列和状态变量实现线程的等待和触发。

控制并发访问:
Semaphore:Semaphore 是一个计数信号量,允许有限数量的线程访问某些资源。它通过 AQS 来管理可用信号量的数量,确保线程能够按顺序获取信号量并进行阻塞与唤醒。

下面举两个例子:

ReentrantLock

咱们使用ReentrantLock锁最多的方式就是tryLock
下面是ReetrantLock源代码

//tryLock调用sync.nonfairTryAcquire(1),传入参数1
public boolean tryLock() {return sync.nonfairTryAcquire(1);}

可以看到nonfairTryAcquire方法在抽象类Sync中并继承了AQS
像里面很多方法都使用的是AQS类中的方法,以及AQS继承类中的方法,例如setExclusiveOwnerThread和getExclusiveOwnerThread方法
在这里插入图片描述

Semaphore

Semaphore(信号量)是 Java 中的一种并发控制工具类,位于 java.util.concurrent 包中。信号量主要用于控制对共享资源的访问,并通过控制允许并发访问的线程数量来限制资源的竞争。它常用于实现资源池、限流等场景。

信号量的基本原理是通过一个计数器来控制同时可以访问共享资源的线程数量。每当一个线程成功获取信号量时,信号量的计数器减少;当一个线程释放信号量时,计数器增加。线程会在计数器大于 0 时才能获取信号量,计数器为 0 时线程会被阻塞,直到有线程释放信号量。

常用的方法
acquire以及release

    @Overridepublic void run() {try {// 请求信号量,如果信号量可用,计数器减 1semaphore.acquire();System.out.println(Thread.currentThread().getName() + " is accessing the resource");// 模拟操作Thread.sleep(2000);} catch (InterruptedException e) {Thread.currentThread().interrupt();} finally {// 释放信号量,计数器加 1semaphore.release();System.out.println(Thread.currentThread().getName() + " has released the resource");}}

一下是Semaphore类的源代码

    public void acquire() throws InterruptedException {sync.acquireSharedInterruptibly(1);}

使用了sync类中的acquireSharedInterruptibly方法
可以看见Semaphore类中有个抽象内部类继承了AQS
在这里插入图片描述

相关文章:

java AQS

什么是AQS AQS(AbstractQueuedSynchronizer,抽象队列同步器)是 Java 中并发控制的一种机制,位于 java.util.concurrent.locks 包下,它为构建锁、信号量等同步工具提供了一个框架。AQS 通过 队列 来管理多个线程之间的…...

L25.【LeetCode笔记】 三步问题的四种解法(含矩阵精彩解法!)

目录 1.题目 2.三种常规解法 方法1:递归做 ​编辑 方法2:改用循环做 初写的代码 提交结果 分析 修改后的代码 提交结果 for循环的其他写法 提交结果 方法3:循环数组 提交结果 3.方法4:矩阵 算法 代码实践 1.先计算矩阵n次方 2.后将矩阵n次方嵌入递推式中 提…...

sdut-C语言实验-合数分解

sdut-C语言实验-合数分解 分数 12 全屏浏览 切换布局 作者 马新娟 单位 山东理工大学 合数是指在大于1的整数中,除了1和本身外,还能被其他数整除的数。‌例如,4、6、8、9、10等都是合数。把一个合数分解成若干个质因数乘积的形式(即求质因…...

深入理解 pytest Fixture 方法及其应用

在 Python 自动化测试领域,pytest 是当之无愧的王者。提到 pytest,不得不说它的一大核心功能——Fixture。Fixture 的强大,让复杂的测试流程变得井井有条,让测试代码更加灵活和可复用。 那么,pytest 的 Fixture 究竟是…...

在Linux上获取MS(如Media Server)中的RTP流并录制为双轨PCM格式的WAV文件

在Linux上获取MS(如Media Server)中的RTP流并录制为双轨PCM格式的WAV文件 一、RTP流与WAV文件格式二、实现步骤三、伪代码示例四、C语言示例代码五、关键点说明六、总结在Linux操作系统上,从媒体服务器(如Media Server,简称MS)获取RTP(Real-time Transport Protocol)流…...

Midjourney技术浅析(八):交互与反馈

Midjourney 的用户交互与反馈通过用户输入(User Input)和用户反馈(User Feedback)机制,不断优化和改进图像生成的质量和用户满意度。 一、用户交互与反馈模块概述 用户交互与反馈模块的主要功能包括: 1.…...

【Spring MVC 核心机制】核心组件和工作流程解析

在 Web 应用开发中,处理用户请求的逻辑常常会涉及到路径匹配、请求分发、视图渲染等多个环节。Spring MVC 作为一款强大的 Web 框架,将这些复杂的操作高度抽象化,通过组件协作简化了开发者的工作。 无论是处理表单请求、生成动态页面&#x…...

回归问题的等量分层

目录 一、说明 二、什么是分层抽样? 三、那么回归又如何呢? 四、回归分层(Stratification on Regression) 一、说明 在同一个数据集中,我们可以看成是一个抽样体。然而,我们如果将这个抽样体分成两份&#…...

Unity-Mirror网络框架-从入门到精通之Basic示例

文章目录 前言Basic示例场景元素预制体元素代码逻辑BasicNetManagerPlayer逻辑SyncVars属性Server逻辑Client逻辑 PlayerUI逻辑 最后 前言 在现代游戏开发中,网络功能日益成为提升游戏体验的关键组成部分。Mirror是一个用于Unity的开源网络框架,专为多人…...

CSS 图片廊:网页设计的艺术与技巧

CSS 图片廊:网页设计的艺术与技巧 引言 在网页设计中,图片廊是一个重要的组成部分,它能够以视觉吸引的方式展示图片集合,增强用户的浏览体验。CSS(层叠样式表)作为网页设计的主要语言之一,提供…...

AI 发展的第一驱动力:人才引领变革

在科技蓬勃发展的当下,AI 成为了时代的焦点,然而其发展并非一帆风顺,究竟什么才是推动 AI 持续前行的关键力量呢? 目录 AI 发展现状剖析 期望与现实的落差 落地困境根源 人才:AI 发展的核心动力​编辑 技术突破的…...

[创业之路-229]:《华为闭环战略管理》-5-平衡记分卡与战略地图

目录 一、平衡记分卡 1. 财务角度: 2. 客户角度: 3. 内部运营角度: 4. 学习与成长角度: 二、BSC战略地图 1、核心内容 2、绘制目的 3、绘制方法 4、注意事项 一、平衡记分卡 平衡记分卡(Balanced Scorecard&…...

用uniapp写一个播放视频首页页面代码

效果如下图所示 首页有导航栏&#xff0c;搜索框&#xff0c;和视频列表&#xff0c; 导航栏如下图 搜索框如下图 视频列表如下图 文件目录 视频首页页面代码如下 <template> <view class"video-home"> <!-- 搜索栏 --> <view class…...

【视觉SLAM:八、后端Ⅰ】

视觉SLAM的后端主要解决状态估计问题&#xff0c;它是优化相机轨迹和地图点的过程&#xff0c;从数学上看属于非线性优化问题。后端的目标是结合传感器数据&#xff0c;通过最优估计获取系统的状态&#xff08;包括相机位姿和场景结构&#xff09;&#xff0c;在状态估计过程中…...

PaddleOCROCR关键信息抽取训练过程

步骤1&#xff1a;python版本3.8.20 步骤2&#xff1a;下载代码&#xff0c;安装依赖 git clone https://gitee.com/PaddlePaddle/PaddleOCR.git pip uninstall opencv-python -y # 安装PaddleOCR的依赖 ! pip install -r requirements.txt # 安装关键信息抽取任务的依赖 !…...

用Python操作字节流中的Excel文档

Python能够轻松地从字节流中加载文件&#xff0c;在不依赖于外部存储的情况下直接对其进行读取、修改等复杂操作&#xff0c;并最终将更改后的文档保存回字节串中。这种能力不仅极大地提高了数据处理的灵活性&#xff0c;还确保了数据的安全性和完整性&#xff0c;尤其是在网络…...

python 桶排序(Bucket Sort)

桶排序&#xff08;Bucket Sort&#xff09; 桶排序是一种分布式排序算法&#xff0c;适用于对均匀分布的数据进行排序。它的基本思想是&#xff1a;将数据分到有限数量的桶中&#xff0c;每个桶分别排序&#xff0c;最后将所有桶中的数据合并。 桶排序的步骤&#xff1a; 划…...

Elasticsearch:探索 Elastic 向量数据库的深度应用

Elasticsearch&#xff1a;探索 Elastic 向量数据库的深度应用 一、Elasticsearch 向量数据库简介 1. Elasticsearch 向量数据库的概念 Elasticsearch 本身是一个基于 Lucene 的搜索引擎&#xff0c;提供了全文搜索和分析的功能。随着技术的发展&#xff0c;Elasticsearch 也…...

【每日学点鸿蒙知识】属性变量key、waterflow卡顿问题、包无法上传、Video控件播放视频、Vue类似语法

1、HarmonyOS 属性变量常量是否可以作为object对象的key&#xff1f; a: object new Object() this.a[Constants.TEST_KEY] "456" 可以先定义&#xff0c;再赋值 2、首页点击回到waterflow的首节点&#xff0c;0~index全部节点被重建&#xff0c;导致卡顿 使用s…...

小程序中引入echarts(保姆级教程)

hello hello~ &#xff0c;这里是 code袁~&#x1f496;&#x1f496; &#xff0c;欢迎大家点赞&#x1f973;&#x1f973;关注&#x1f4a5;&#x1f4a5;收藏&#x1f339;&#x1f339;&#x1f339; &#x1f981;作者简介&#xff1a;一名喜欢分享和记录学习的在校大学生…...

基于 Node.js 的 ORM(对象关系映射)工具——Sequelize介绍与使用,并举案例分析

便捷性介绍 支持多种数据库&#xff0c;包括 PostgreSQL、MySQL、MariaDB、SQLite 和 Microsoft SQL Server。Sequelize 提供了丰富的功能&#xff0c;帮助开发者用 JavaScript&#xff08;或 TypeScript&#xff09;代码操作数据库&#xff0c;而无需直接书写 SQL 语句。 Se…...

python 插入排序(Insertion Sort)

插入排序&#xff08;Insertion Sort&#xff09; 插入排序是一种简单的排序算法。它的基本思想是&#xff1a;将数组分为已排序部分和未排序部分&#xff0c;然后逐个将未排序部分的元素插入到已排序部分的正确位置。插入排序类似于整理扑克牌的过程。 插入排序的步骤&#…...

电子应用设计方案81:智能AI冲奶瓶系统设计

智能 AI 冲奶瓶系统设计 一、引言 智能 AI 冲奶瓶系统旨在为父母或照顾者提供便捷、准确和卫生的冲奶服务&#xff0c;特别是在夜间或忙碌时&#xff0c;减轻负担并确保婴儿获得适宜的营养。 二、系统概述 1. 系统目标 - 精确调配奶粉和水的比例&#xff0c;满足不同年龄段婴…...

JAVA高并发总结

JAVA高并发编程总结 在现代应用中&#xff0c;高并发编程是非常重要的一部分&#xff0c;尤其是在分布式系统、微服务架构、实时数据处理等领域。Java 提供了丰富的并发工具和技术&#xff0c;帮助开发者在多线程和高并发的场景下提高应用的性能和稳定性。以下是 Java 高并发编…...

【AIGC】使用Java实现Azure语音服务批量转录功能:完整指南

文章目录 引言技术背景环境准备详细实现1. 基础架构设计2. 实现文件上传功能3. 提交转录任务crul4. 获取转录结果 使用示例结果示例最佳实践与注意事项总结 引言 在当今数字化时代&#xff0c;将音频内容转换为文本的需求越来越普遍。无论是会议记录、视频字幕生成&#xff0c…...

arcgis模版空库怎么用(一)

这里以某个项目的数据为例&#xff1a; 可以看到&#xff0c;属性表中全部只有列标题&#xff0c;无数据内容 可能有些人会认为空库是用来往里面加入信息的&#xff0c;其实不是&#xff0c;正确的用法如下&#xff1a; 一、下图是我演示用的数据&#xff0c;我们可以看到其中…...

【电机控制】基于STC8H1K28的六步换向——方波驱动(软件篇)

【电机控制】基于STC8H1K28的六步换向——方波驱动&#xff08;软件篇&#xff09; 文章目录 [TOC](文章目录) 前言一、main.c二、GPIO.c三、PWMA.c四、ADC.c五、CMP.c六、Timer.c七、PMSM.c八、参考资料总结 前言 【电机控制】STC8H无感方波驱动—反电动势过零检测六步换向法 …...

小程序配置文件 —— 13 全局配置 - window配置

全局配置 - window配置 这里讲解根目录 app.json 中的 window 字段&#xff0c;window 字段用于设置小程序的状态栏、导航条、标题、窗口背景色&#xff1b; 状态栏&#xff1a;顶部位置&#xff0c;有网络信号、时间信息、电池信息等&#xff1b;导航条&#xff1a;有一个当…...

全球域名市场科普之域名交易平台介绍——Sedo与Afternic

关于Dynadot Dynadot是通过ICANN认证的域名注册商&#xff0c;自2002年成立以来&#xff0c;服务于全球108个国家和地区的客户&#xff0c;为数以万计的客户提供简洁&#xff0c;优惠&#xff0c;安全的域名注册以及管理服务。 Dynadot平台操作教程索引&#xff08;包括域名邮…...

leetcode108:将有序数组转化为二叉搜索树

给你一个整数数组 nums &#xff0c;其中元素已经按 升序 排列&#xff0c;请你将其转换为一棵 平衡 二叉搜索树。 示例 1&#xff1a; 输入&#xff1a;nums [-10,-3,0,5,9] 输出&#xff1a;[0,-3,9,-10,null,5] 解释&#xff1a;[0,-10,5,null,-3,null,9] 也将被视为正确…...