抽象同步队列AbstractQueuedSynchronizer(AQS)简要理解

news2025/1/15 8:07:46

抽象同步队列AbstractQueuedSynchronizer AQS 简要理解

  • 1 什么是AQS
  • 2 AQS结构
    • 2.1 同步状态
    • 2.2 CLH队列
    • 2.3 Node
  • 3 AQS流程

https://zhuanlan.zhihu.com/p/370501087

1 什么是AQS

AQS(AbstractQueuedSynchronizer)是 Java 中实现锁和同步器的基础设施,它是一个抽象类,提供了构建锁和同步器的基本框架,可以用于实现 ReentrantLock、Semaphore、CountDownLatch 等同步器。A Q S定义了一套多线程访问共享资源的同步模板,解决了实现同步器时涉及的大量细节问题,能够极大地减少实现工作。

2 AQS结构

state同步状态、Node组成的CLH队列、ConditionObject条件变量(包含Node组成的条件单向队列)。在这里插入图片描述

2.1 同步状态

对于A Q S来说,线程同步的关键是对state的操作,可以说获取、释放资源是否成功都是由state决定的,比如state>0代表可获取资源,否则无法获取,所以state的具体语义由实现者去定义,现有的ReentrantLock、ReentrantReadWriteLock、Semaphore、CountDownLatch定义的state语义都不一样。

  • ReentrantLock的state用来表示是否有锁资源
  • ReentrantReadWriteLock的state高16位代表读锁状态,低16位代表写锁状态
  • Semaphore的state用来表示可用信号的个数
  • CountDownLatch的state用来表示计数器的值

2.2 CLH队列

CLH是AQS内部维护的FIFO(先进先出)双端双向队列(方便尾部节点插入),基于链表数据结构,当一个线程竞争资源失败,就会将等待资源的线程封装成一个Node节点,通过CAS原子操作插入队列尾部,最终不同的Node节点连接组成了一个CLH队列,所以说AQS通过CLH队列管理竞争资源的线程。
在AQS的实现中,如果线程在获取锁时发现锁已经被占用,那么此时线程将进入自旋等待。自旋等待的次数由重入次数和内部逻辑决定,如果自旋等待时间过长或获取不到锁,线程将转入阻塞状态。通过 acquire() 和 release() 接口向队列中添加或移除等待线程。

  • acquire() 中,AQS 会使用 CAS 操作来尝试获得锁,如果获得失败,则会将当前线程加入到等待队列中
  • release() 中,AQS 则会唤醒等待队列中的线程,使其有机会再次尝试获取锁。

什么是CAS
CAS(Compare-and-Swap)是一种原子性操作,用于实现并发编程中的同步机制。CAS 操作可用于多线程之间进行协作,确保只有一个线程可以对某个共享变量进行修改。

期望对象为某个值并设置为新的值。那么,如果不为期望的值或更新值失败,返回false;如果为期望的值并且设置成功,那么返回true。CAS 操作通常包含三个参数:

  • 内存地址 V:用于指示需要更新的值的内存地址。
  • 预期值 A:用于指示存储在 V 中的预期值,即当前值。
  • 新值 B:用于指示需要将 V 更新为的新值。

什么是自旋?
自旋是一种在线程等待锁或资源时的暂停方式。当一个线程在获取锁或者等待资源时,如果发现资源被占用并不会立即被释放,那么该线程将不会进入阻塞状态,而是一直循环询问资源状态是否可用,此时该线程就处于自旋状态,循环执行一段无意义的指令,直到获取到锁或资源后再继续执行下去。

自旋可以减少线程的阻塞和唤醒的次数,从而减少线程上下文切换的开销,提高整个系统的运行效率。因为当线程竞争的资源较少时,自旋等待是比较有效的,而当资源竞争比较激烈时,自旋等待会导致大量的资源浪费,此时需要使用其他方式进行线程等待。

需要注意的是,自旋等待不适用于所有场景。当线程等待时间较长时,自旋等待可能会显著影响系统性能,此时可以使用线程阻塞或其他方式实现等待。此外,自旋等待还可能会导致CPU资源的浪费,因此需要根据实际情况进行选择和使用。

CLH队列的优点

  • 先进先出保证了公平性
  • 非阻塞的队列,通过自旋锁和C A S保证节点插入和移除的原子性,实现无锁快速插入
  • 采用了自旋锁思想,所以CLH也是一种基于链表的可扩展、高性能、公平的自旋锁
  • 由于每个线程只需要关注自己的前驱节点,因此减少了不必要的锁竞争,提高了锁竞争的效率
  • 同时,CLH队列通过自适应的方式来扩展队列,可以根据需要动态分配、释放队列节点,且不会出现竞争情况。

2.3 Node

Node是A Q S的内部类,每个等待资源的线程都会封装成Node节点组成C L H队列、等待队列。
在这里插入图片描述

3 AQS流程

线程获取资源失败,封装成Node节点从C L H队列尾部入队并阻塞线程,某线程释放资源时会把C L H队列首部Node节点关联的线程唤醒,再次获取资源。
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/435771.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

el-input-number中添加单位(css版)

优点: 通过css添加,非常便捷和简单 例如此处,需要添加一个分钟单位 <el-input-number class"input-number" v-model"value" :step"5" :min"30" ></el-input-number> //css <style lang"scss"> .input-nu…

node项目(一) koa脚手架的搭建

一、koa 安装 // 安装koa npm install -g koa-generator // 创建项目 koa2 项目名称 当出现这个框的时候安装完毕 之后就是进入目录文件&#xff0c;根据package.json执行即可 二、出现问题 汇总 问题一&#xff1a;koa-generator安装失败 没有出现koa-generator安装成功 …

分类预测 | MATLAB实现BO-CNN-GRU贝叶斯优化卷积门控循环单元多输入分类预测

分类预测 | MATLAB实现BO-CNN-GRU贝叶斯优化卷积门控循环单元多输入分类预测 目录 分类预测 | MATLAB实现BO-CNN-GRU贝叶斯优化卷积门控循环单元多输入分类预测效果一览基本介绍模型描述程序设计参考资料 效果一览 基本介绍 基于贝叶斯(bayes)优化卷积神经网络-门控循环单元(CN…

4月第2周榜单丨飞瓜数据B站UP主排行榜(哔哩哔哩平台)发布!

飞瓜轻数发布2023年4月10日-4月16日飞瓜数据UP主排行榜&#xff08;B站平台&#xff09;&#xff0c;通过充电数、涨粉数、成长指数三个维度来体现UP主账号成长的情况&#xff0c;为用户提供B站号综合价值的数据参考&#xff0c;根据UP主成长情况用户能够快速找到运营能力强的B…

Linux进程概念——其一

目录 冯诺依曼体系结构 操作系统(Operator System) 概念 设计OS的目的 定位 如何理解 "管理" 总结 系统调用和库函数概念 进程 基本概念 描述进程-PCB task_struct-PCB的一种 task_ struct内容分类 组织进程 查看进程 通过系统调用获取进程标示符 通…

Docker Desktop 占用过多C盘存储空间的一种解决办法——在其他磁盘分区添加访问路径

一、问题背景 Docker Desktop默认是安装到C盘中的。但随着Docker的使用&#xff0c;其占用的空间也越来越大&#xff0c;Docker占用C盘空间过大成了个令人头疼的问题。恰好最近腾出了一个空的磁盘分区&#xff0c;因此可以使用“在其他磁盘分区添加访问路径”的方式&#xff0c…

03-Mybatis的基本使用-注解配置文件+xml配置文件

目录 1、环境准备 2、注解配置文件 基础操作01-通过ID删除数据 基础操作02-插入数据 基础操作03-更新数据 基础操作04-根据ID查询数据 基础操作05-条件查询数据 3、xml配置文件 1、环境准备 1. 创建数据库数据表 -- 部门管理 create table dept(id int unsigned prim…

【数据篇】SpringBoot 整合 MyBatis 组合 Redis 作为数据源缓存

写在最前 MyBatis 是常见的 Java 数据库访问层框架。在日常工作中&#xff0c;开发人员多数情况下是使用 MyBatis 的默认缓存配置&#xff0c;但是 MyBatis 缓存机制有一些不足之处&#xff0c;在使用中容易引起脏数据&#xff0c;形成一些潜在的隐患。 本文介绍的是 Redis 组…

版本控制工具之git安装

作为软件开发者的必备工具——版本控制工具&#xff0c;git无疑深受欢迎。 业界常用的版本控制工具主要有两种&#xff1a;SVN和Git SVN 传统的版本控制工具&#xff0c;特点为集中式分布。 使用一台专用的服务器存储所有资料。 缺点是所有的动作都必须依赖于中央服务器&#x…

FPGA配置方式的基本知识?

FPGA配置粗略可以分为主动和被动两种。主动加载是指由FPGA控制配置流程&#xff0c;被动加载是指FPGA仅仅被动接收配置数据。 最常见的被动配置模式就是JTAG下载bit文件。此模式下&#xff0c;主动发起操作的设备是计算机&#xff0c;数据通路是JTAG&#xff0c;FPGA会被动接收…

STM32F103基于HAL库I2C/SPI硬件接口+DMA驱动 SSD1306 Oled

STM32F103基于HAL库I2C/SPI硬件接口DMA驱动 SSD1306 Oled ✨由于手上只有I2C接口的SSD1306 OLED屏幕&#xff0c;仅测试了硬件I2C驱动显示功能&#xff0c;实际测试的FPS帧率在37或38变化。 &#x1f4e2;本项目从Github开源项目中移植过来&#xff0c;开源地址&#xff1a;htt…

JDBC之API详解

DriverManager可以注册驱动&#xff0c;就是创建接口的实现类对象。 Class.forName可以将Driver类加载进内存&#xff0c;Driver类中存在静态代码块&#xff0c;随着类的加载静态代码块执行&#xff0c;通过 DriverManager.registerDriver的方式注册好驱动。 获取与数据库的链…

Android Java 播放音频 AudioTrack

【很多同学读 Android 系统的源码时感觉比较费力&#xff0c;一定会觉得是自己水平不够见识有限认知水平不足&#xff0c;觉得自己需要多学习多努力多下功夫&#xff0c;但 Android 系统源码质量之烂简直超乎想象。尽管 Android 系统确实实现了很多功能、特性&#xff0c;提供了…

【面试】你在项目中遇到过慢查询问题吗?你是怎么做SQL优化的?

文章目录 前言一、找出有问题的SQL1、系统层面2、SQL语句层面 二、查看SQL执行计划三、SQL优化案例慢查询优化步骤 SQL优化小结 前言 我在面试的时候很喜欢问候选人这样一个问题&#xff1a;“你在项目中遇到过慢查询问题吗&#xff1f;你是怎么做SQL优化的&#xff1f;” 很多…

含分布式电源的配电网可靠性评估研究(Matlab代码实现)

&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑清晰&#xff0c;为了方便读者。 ⛳️座右铭&a…

Windows服务搭建web网站,使用cpolar内网穿透实现公网访问

文章目录 概述1. 搭建一个静态Web站点2. 本地浏览测试站点是否正常3. 本地站点发布公网可访问3.1 安装cpolar内网穿透3.2 创建隧道映射公网地址3.3 获取公网URL地址 4. 公网远程访问内网web站点5. 配置固定二级子域名5.1 保留二级子域名5.2 配置二级子域名 6. 测试访问二级子域…

Activiti7 工作流非原流程终止

背景 正常工作流&#xff0c;需要经过 node1、node2 才能结束。 现在要求已经开启的流程&#xff0c;目前停留在 node1&#xff0c;可以提前终止。 方案 一般根据实际需要&#xff0c;可以有几种做法&#xff1a; 新绘制流程图&#xff0c;新增 node1 结束的流程分支&#x…

基于 JESD204B 协议ARM+FPGA+AD多板卡多通道同步采集实现方法

0 引言 随着数字化信号处理技术的不断进步&#xff0c;对数字信号 的处理已经成为当前大多数工程应用的基本方法。由于 模拟信号才是现实生活中的原始信号&#xff0c;为了工程研究实 现的可能&#xff0c;需将模拟信号转换为数字信号才能在工程中 处理&#xff0c;AD 转换…

独立按键控制LED移位

1.这就是LED移位的原理 2. #include <REGX52.H> void Delay(unsigned int xms);unsigned char LEDNum;//LEDNum为0000 0000void main() {P2~0x01; //上电默认LED1点亮while(1){if(P3_10) //如果K1按键按下&#xff0c;LED灯往右依次亮起{Delay(20);while(P3_10);//消…

Bandizip已管理员身份运行

系列文章目录 文章目录 系列文章目录前言一、Bandzib是什么&#xff1f;二、使用步骤1.引入库 前言 在解压krita源码包时Bandizip报错 一、Bandzib是什么&#xff1f; bandzip官网 Bandizip 是一款压缩软件&#xff0c;它支持Zip、7-Zip 和 RAR 以及其它压缩格式。它拥有非…