AbstractQueuedSynchronizer
目录
- AQS是什么
- AQS什么样
- 内部类
- 成员变量
- 方法public
- 如果不使用AQS会怎样
- AQS的应用
- ReentrantLock
- Sync
- NonfairSync
- FairSync
- 其他实现
AQS是什么
AbstractQueuedSynchronizer
(AQS)是Java中的一个并发工具,位于java.util.concurrent.locks
包中,用于实现基于锁的同步机制。它是许多同步类(如ReentrantLock
和Semaphore
等)的基础,并提供了一种用于实现独占锁(exclusive locks)和共享锁(shared locks)等同步机制的框架。
AQS是一个抽象类,它通过维护一个等待队列来管理线程的同步状态。它的主要设计思想是,当某个线程尝试获取锁时,如果锁不可用,该线程会被放入等待队列,然后被阻塞。当锁释放时,AQS会从等待队列中唤醒适当的线程,使其能够竞争锁。
AQS什么样
内部类
类名 | 作用 |
---|---|
Node | Node 类表示等待队列中的一个节点,用于构建等待队列、实现线程的阻塞与唤醒,以及表示等待线程。 |
ExclusiveNode | ExclusiveNode 是Node 类的子类,表示独占模式(exclusive mode)下的节点,用于独占锁的等待队列。 |
SharedNode | SharedNode 是Node 类的子类,表示共享模式(shared mode)下的节点,用于共享锁的等待队列。 |
ConditionNode | ConditionNode 是Node 类的子类,表示条件等待队列中的节点,用于支持条件变量的等待和唤醒机制。 |
ConditionObject | ConditionObject 是AbstractQueuedSynchronizer 的内部类,用于实现条件变量,允许线程等待特定条件。 |
这些内部类在AbstractQueuedSynchronizer
的实现中扮演着不同的角色,从构建等待队列、表示等待线程、实现条件等待机制,到支持不同模式的锁等待。通过这些内部类的使用,AQS能够支持各种同步场景和锁的实现,从而实现多线程的协调和同步。
成员变量
先看看AQS里都有哪些成员变量:
当然,我可以为您解释这些成员变量的作用。以下是您列出的成员变量的简要解释和作用的表格展示:
变量名 | 变量类型 | 变量作用 |
---|---|---|
WAITING | int | 表示线程处于等待状态,即等待获取锁。 |
CANCELLED | int | 表示线程在等待队列中等待时被取消,即等待被中断或其他原因取消。 |
COND | Node | 一个特殊的标识,用于表示等待队列中的节点是一个条件等待节点而不是独占或共享模式的节点。 |
head | Node | 等待队列中的头节点,即队列中等待时间最长的节点。 |
tail | Node | 等待队列中的尾节点,即队列中等待时间最短的节点。 |
state | int | 表示同步状态的变量,可以是任意整数值,根据具体实现的需要来表示不同的状态。 |
U | Unsafe | 提供了一些底层的操作,允许直接对内存进行操作,用于实现一些底层同步原语。 |
STATE | long | 一个偏移量,用于表示在AbstractQueuedSynchronizer 类中用于操作state 变量的偏移量。 |
HEAD | long | 一个偏移量,用于表示在AbstractQueuedSynchronizer 类中用于操作head 变量的偏移量。 |
TAIL | long | 一个偏移量,用于表示在AbstractQueuedSynchronizer 类中用于操作tail 变量的偏移量。 |
这些成员变量在AbstractQueuedSynchronizer
中用于维护等待队列、线程状态和同步状态等信息,从而实现了基于队列的线程同步和协调机制。不同的变量在整个机制中扮演着不同的角色,以实现正确的多线程同步行为。
方法public
我们来看一下AQS都提供了哪些方法
方法名 | 参数含义 | 方法作用 |
---|---|---|
acquire | int arg:请求获取锁的参数 | 尝试获取锁,如果获取不到则将调用线程置于阻塞状态,直到锁可用或线程被中断。 |
acquireInterruptibly | int arg:请求获取锁的参数 | 类似于acquire ,但是允许线程在等待锁的过程中被中断。如果线程在等待时被中断,会抛出InterruptedException 异常。 |
tryAcquireNanos | int arg:请求获取锁的参数,long nanosTimeout:等待时间 | 尝试获取锁,但最多等待指定的时间。如果在超时前未能获取锁,则返回结果指示是否成功获取。 |
release | int arg:释放锁的参数 | 释放锁,通常在获取锁成功后调用。释放锁会唤醒等待队列中的其他线程,使其有机会竞争锁。 |
acquireShared | int arg:请求获取共享锁的参数 | 类似于acquire ,但是用于共享锁的获取。多个线程可以同时获取共享锁,而不像独占锁一样只能有一个线程持有。 |
acquireSharedInterruptibly | int arg:请求获取共享锁的参数 | 类似于acquireShared ,但是允许线程在等待共享锁的过程中被中断。如果线程在等待时被中断,会抛出InterruptedException 异常。 |
tryAcquireSharedNanos | int arg:请求获取共享锁的参数,long nanosTimeout:等待时间 | 类似于tryAcquireNanos ,但是用于共享锁的获取。 |
releaseShared | int arg:释放共享锁的参数 | 释放共享锁,通常在获取共享锁成功后调用。释放共享锁会唤醒等待队列中的其他线程,使其有机会竞争锁。 |
hasQueuedThreads | - | 判断是否有线程在等待队列中等待获取锁。 |
hasContended | - | 判断是否有线程在竞争锁。 |
getFirstQueuedThread | - | 获取等待队列中的第一个线程,但不移除。 |
isQueued | Thread thread:要检查的线程 | 判断指定线程是否在等待队列中等待获取锁。 |
apparentlyFirstQueuedIsExclusive | - | 判断等待队列中的第一个线程是否为独占模式(exclusive mode)线程。 |
hasQueuedPredecessors | - | 判断调用线程是否有在等待队列中的前驱线程。如果有前驱线程,则可能需要执行阻塞操作。 |
getQueueLength | - | 获取等待队列中的线程数。 |
getQueuedThreads | - | 获取在等待队列中等待获取锁的所有线程。 |
getExclusiveQueuedThreads | - | 获取在等待队列中等待获取独占锁的所有线程。 |
getSharedQueuedThreads | - | 获取在等待队列中等待获取共享锁的所有线程。 |
toString | - | 返回对象的字符串表示,通常包括等待队列中的线程信息。 |
owns | Thread thread:要检查的线程 | 判断指定线程是否是当前持有锁的线程。 |
hasWaiters | - | 判断是否有线程在等待队列中等待释放锁。 |
getWaitQueueLength | - | 获取等待队列中等待释放锁的线程数。 |
getWaitingThreads | Condition condition:相关的条件 | 获取与指定条件相关的等待线程列表。 |
这些方法是AbstractQueuedSynchronizer
类的核心方法,用于实现多线程同步和协调。
如果不使用AQS会怎样
AQS的应用
我们来直接举个例子
ReentrantLock
ReentrantLock中有3个内部类
Sync
AQS的子类,其实基本上实现了ReentrentLock的大部分方法,ReentrentLock开放出来的大部分方法其实都是直接调用的Sync里的方法
方法名 | 参数含义 | 方法作用 |
---|---|---|
tryLock | long timeout, TimeUnit unit | 尝试获取锁,如果锁没有被其他线程持有,则获取锁并返回true,如果在指定的时间内无法获取锁,则返回false。 |
initialTryLock | - | 作为tryLock的一种形式,是在ReentrantLock的构造函数中使用的,用于初始化锁。 |
lock | - | 获取锁,如果锁已经被其他线程持有,则当前线程会被阻塞,直到获取到锁。 |
lockInterruptibly | - | 获取锁,如果锁已经被其他线程持有,允许线程在等待时被中断。如果线程在等待时被中断,会抛出InterruptedException异常。 |
tryLockNanos | long timeout | 尝试在指定的时间内获取锁,如果锁没有被其他线程持有,则获取锁并返回true。如果在指定的时间内无法获取锁,则返回false。 |
tryRelease | - | 尝试释放锁。 |
isHeldExclusively | - | 判断当前线程是否持有独占锁。 |
newCondition | - | 创建一个新的Condition对象,用于支持条件等待。 |
getOwner | - | 获取当前持有独占锁的线程,如果没有线程持有锁,返回null。 |
getHoldCount | - | 获取当前线程持有锁的次数,用于可重入锁的计数。 |
isLocked | - | 判断锁是否被任何线程持有。 |
NonfairSync
Sync的子类,非公平锁的实现。
方法名 | 参数 | 作用 |
---|---|---|
initialTryLock | unused | 尝试获取锁,如果获取成功返回true,失败返回false。该方法只在构造方法中调用一次。 |
tryAcquire | acquires | 独占式尝试获取同步状态。如果获取成功返回true,否则返回false。 |
FairSync
Sync的子类,公平锁的实现
方法名 | 参数 | 作用 |
---|---|---|
initialTryLock | unused | 尝试获取锁,当等待队列无线程等待并且state为0。不同于NonfairSync,公平锁只有无竞争时才会尝试获取锁。 |
tryAcquire | acquires | 尝试获取同步状态,如果队列中第一个节点是当前线程就获取成功,不是则失败。 |
FairSync也继承自AQS,但实现了公平的锁获取语义 - 等待时间最长的线程最先获得锁。
这两个类开始起作用是在创建ReentrentLock的时候,这里
其他实现
- CountDownLatch: 用来进行线程之间同步协作,可以实现一个线程等待其他线程完成某件事情之后再执行。
- CyclicBarrier: 用来进行线程之间同步协作,可以实现让一组线程达到一个屏障时被阻塞,直到最后一个线程到达屏障时屏障才会开门,所有被屏障拦截的线程才会继续执行。
- Semaphore: 用于控制同时访问特定资源的线程数量,它通过协调各个线程,以保证合理的使用公共资源。
- Exchanger: 用于进行线程间的数据交换。它提供一个同步点,在这个同步点,两个线程可以交换彼此的数据。
- BlockingQueue: 一个支持两个附加操作的队列。在队列为空时,获取元素的线程会等待队列变为非空。当队列满时,存储元素的线程会等待队列可用。
- ForkJoinPool: Fork/Join框架中的线程池实现类,用于异步执行fork/join任务。
相关文章:

AbstractQueuedSynchronizer
目录 AQS是什么AQS什么样内部类成员变量方法public如果不使用AQS会怎样 AQS的应用ReentrantLockSyncNonfairSyncFairSync 其他实现 AQS是什么 AbstractQueuedSynchronizer(AQS)是Java中的一个并发工具,位于java.util.concurrent.locks包中&a…...

谈谈什么是云计算?以及它的应用
作者:Insist-- 个人主页:insist--个人主页 作者会持续更新网络知识和python基础知识,期待你的关注 目录 编辑 一、什么是云计算 二、云计算的优势与劣势? 1、云计算的优势 ①提高资源利用率 ②提升效率 ③降低成本 2、云…...
【BASH】回顾与知识点梳理(十六)
【BASH】回顾与知识点梳理 十六 十六. 十二至十五章知识点总结及练习16.1 总结16.2 练习16.3 简答题 该系列目录 --> 【BASH】回顾与知识点梳理(目录) 十六. 十二至十五章知识点总结及练习 16.1 总结 绝对路径:『一定由根目录 / 写起』…...

docsify gitee 搭建个人博客
docsify & gitee 搭建个人博客 文章目录 docsify & gitee 搭建个人博客1.npm 安装1.1 在Windows上安装npm:1.2 在macOS上安装npm:1.3 linux 安装npm 2. docsify2.1 安装docsify2.2 自定义配置2.2.1 通过修改index.html,定制化开发页面…...

SpringBoot2-Tomcat部署
1.排除内置 Tomcat 在pom.xml文件中的下添加以下代码,用于排除SpringBoot内置Tomcat <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId><exclusions><exclusion&…...

Docker查看、创建、进入容器相关的命令
1.查看、创建、进入容器的指令 用-it指令创建出来的容器,创建完成之后会立马进入容器。退出之后立马关闭容器。 docker run -it --namec1 centos:7 /bin/bash退出容器: exit查看现在正在运行的容器命令: docker ps查看历史容器࿰…...
leetcode1. 两数之和
题目:leetcode1. 两数之和 描述: 给定一个整数数组 nums 和一个整数目标值 target,请你在该数组中找出 和为目标值 target 的那 两个 整数,并返回它们的数组下标。 你可以假设每种输入只会对应一个答案。但是,数组中…...

温室花卉种植系统springboot框架jsp鲜花养殖智能管理java源代码
本项目为前几天收费帮学妹做的一个项目,Java EE JSP项目,在工作环境中基本使用不到,但是很多学校把这个当作编程入门的项目来做,故分享出本项目供初学者参考。 一、项目描述 基于Git无线传感网络的温室花卉种植智能控制系统 系统…...

测试老鸟经验总结,Jmeter性能测试-重要指标与性能结果分析(超细)
目录:导读 前言一、Python编程入门到精通二、接口自动化项目实战三、Web自动化项目实战四、App自动化项目实战五、一线大厂简历六、测试开发DevOps体系七、常用自动化测试工具八、JMeter性能测试九、总结(尾部小惊喜) 前言 Aggregate Report …...

IDEA设置Maven自动编译model
IDEA设置Maven自动编译model 项目工程结构IDEA maven设置 项目工程结构 假设我们的项目结构是下图这样,也就是一个父工程下包含多个子模块,其中dubbo-01-api是公共模块,其它两个模块要想使用必须在pom文件中引入。 本地开发要想不会报错&am…...
关于本地mockjs的使用
安装mockjs npm install mockjs -s在src下新建目录mockData,所有mock请求可以放该文件夹下面。例如在mockData文件夹下新建一个home.js文件。用来处理首页的请求数据 home.js export default {getHomeData:()>{return{code:200,data:{tableData:[{name:张三,se…...

hive 中最常用日期处理函数
hive 常用日期处理函数 在工作中,日期函数是提取数据计算数据必须要用到的环节。哪怕是提取某个时间段下的明细数据也得用到日期函数。今天和大家分享一下常用的日期函数。为什么说常用呢?其实这些函数在数据运营同学手上是几乎每天都在使用的。 技术交…...

记录一下Java实体转json字段顺序问题
特殊需求,和C交互他们那边要求字段顺序要和他们定义的一致(批框架) 如下: Data public class UserDto {private String name;private Integer age;private String addr; }未转换前打印: 转换后打印: 可以看到转换为json顺序打印…...
微积分入门:总结归纳汇总(一)
基础 标准符号约定: ( s i n x ) n (sinx)^n (sinx)...

ubuntu python虚拟环境venv搭配systemd服务实战(禁用缓存下载--no-cache-dir)
文章目录 参考文章目录结构步骤安装venv查看python版本创建虚拟环境激活虚拟环境运行我们程序看缺少哪些依赖库,依次安装它们接下来我们配置python程序启动脚本,脚本中启动python程序前需先激活虚拟环境配置.service文件然后执行部署脚本,成功…...

案例15 Spring Boot入门案例
1. 选择Spring Initializr快速构建项目 2. 设置项目信息 3. 选择依赖 4. 设置项目名称 5. 项目结构 6. 项目依赖 自动配置了Spring MVC、内置了Tomcat、配置了Logback(日志)、配置了JSON。 7. 创建HelloController类 com.wfit.boot.hello目录下创建HelloCo…...
物联网是下一个风口吗?
随着科技的持续进步,物联网行业正在迅速兴起,展现出巨大的潜力。那么,物联网行业的未来是什么样的呢? 1. 5G技术的广泛应用和普及 随着5G技术的快速发展和商业化推广,物联网行业将迎来一个巨大的飞跃。5G技术的高速传…...

8月9日上课内容 nginx反向代理与负载均衡
负载均衡工作当中用的很多的,也是面试会问的很重要的一个点 负载均衡:通过反向代理来实现(nginx只有反向代理才能做负载均衡) 正向代理的配置方法(用的较少) 反向代理的方式:四层代理与七层代…...

易服客工作室:Elementor AI简介 – 彻底改变您创建网站的方式
Elementor 作为领先的 WordPress 网站构建器,是第一个添加本机 AI 集成的。Elementor AI 的第一阶段将使您能够生成和改进文本和自定义代码(HTML、自定义代码和自定义 CSS)。我们还已经在进行以下阶段的工作,其中将包括基于人工智…...
ClickHouse的数据类型
1.整数型 固定长度的整型,包括有符号整型或无符号整型。整型范围(-2n-1~2n-1-1): Int8 - [-128 : 127] Int16 - [-32768 : 32767] Int32 - [-2147483648 : 2147483647] Int64 - [-9223372036854775808 : 9223372036854775807]无符…...
应用升级/灾备测试时使用guarantee 闪回点迅速回退
1.场景 应用要升级,当升级失败时,数据库回退到升级前. 要测试系统,测试完成后,数据库要回退到测试前。 相对于RMAN恢复需要很长时间, 数据库闪回只需要几分钟。 2.技术实现 数据库设置 2个db_recovery参数 创建guarantee闪回点,不需要开启数据库闪回。…...

Linux相关概念和易错知识点(42)(TCP的连接管理、可靠性、面临复杂网络的处理)
目录 1.TCP的连接管理机制(1)三次握手①握手过程②对握手过程的理解 (2)四次挥手(3)握手和挥手的触发(4)状态切换①挥手过程中状态的切换②握手过程中状态的切换 2.TCP的可靠性&…...

江苏艾立泰跨国资源接力:废料变黄金的绿色供应链革命
在华东塑料包装行业面临限塑令深度调整的背景下,江苏艾立泰以一场跨国资源接力的创新实践,重新定义了绿色供应链的边界。 跨国回收网络:废料变黄金的全球棋局 艾立泰在欧洲、东南亚建立再生塑料回收点,将海外废弃包装箱通过标准…...

《通信之道——从微积分到 5G》读书总结
第1章 绪 论 1.1 这是一本什么样的书 通信技术,说到底就是数学。 那些最基础、最本质的部分。 1.2 什么是通信 通信 发送方 接收方 承载信息的信号 解调出其中承载的信息 信息在发送方那里被加工成信号(调制) 把信息从信号中抽取出来&am…...
解决本地部署 SmolVLM2 大语言模型运行 flash-attn 报错
出现的问题 安装 flash-attn 会一直卡在 build 那一步或者运行报错 解决办法 是因为你安装的 flash-attn 版本没有对应上,所以报错,到 https://github.com/Dao-AILab/flash-attention/releases 下载对应版本,cu、torch、cp 的版本一定要对…...

Ascend NPU上适配Step-Audio模型
1 概述 1.1 简述 Step-Audio 是业界首个集语音理解与生成控制一体化的产品级开源实时语音对话系统,支持多语言对话(如 中文,英文,日语),语音情感(如 开心,悲伤)&#x…...

12.找到字符串中所有字母异位词
🧠 题目解析 题目描述: 给定两个字符串 s 和 p,找出 s 中所有 p 的字母异位词的起始索引。 返回的答案以数组形式表示。 字母异位词定义: 若两个字符串包含的字符种类和出现次数完全相同,顺序无所谓,则互为…...
大数据学习(132)-HIve数据分析
🍋🍋大数据学习🍋🍋 🔥系列专栏: 👑哲学语录: 用力所能及,改变世界。 💖如果觉得博主的文章还不错的话,请点赞👍收藏⭐️留言Ǵ…...

深入浅出深度学习基础:从感知机到全连接神经网络的核心原理与应用
文章目录 前言一、感知机 (Perceptron)1.1 基础介绍1.1.1 感知机是什么?1.1.2 感知机的工作原理 1.2 感知机的简单应用:基本逻辑门1.2.1 逻辑与 (Logic AND)1.2.2 逻辑或 (Logic OR)1.2.3 逻辑与非 (Logic NAND) 1.3 感知机的实现1.3.1 简单实现 (基于阈…...

使用LangGraph和LangSmith构建多智能体人工智能系统
现在,通过组合几个较小的子智能体来创建一个强大的人工智能智能体正成为一种趋势。但这也带来了一些挑战,比如减少幻觉、管理对话流程、在测试期间留意智能体的工作方式、允许人工介入以及评估其性能。你需要进行大量的反复试验。 在这篇博客〔原作者&a…...