Java中AQS的介绍及实现原理

为了带你精通 Java AQS,我画了 40 张图,从管程模型讲起! AQS 使用 FIFO 队列实现了一个锁相关的并发器模板,可以基于这个模板来实现各种锁,包括独占锁、共享锁、信号量等。AQS 中,有一个核心状态是 waitStatus,这个代表节点的状态,决定了当前节点的后续操作,比如是否等待唤醒,是否要唤醒后继节点。AQS 基于双向队列实现了入口等待队列,基于 state 变量实现了各种并发锁,上篇文章讲了入口等待队列,而这篇文章主要讲了基于 AQS 的并发锁原理。 阅读详情

Java中AQS的实现原理

什么是AQS

AQS全称是AbstractQueuedSynchronizer,是Java并发包中的一个基础组件,用于实现大部分的同步器实现。AQS提供了一种简单的机制来构建具有复杂同步需求的同步器,如ReentrantLock、Semaphore、CountDownLatch等都是基于AQS实现的。

AQS提供了一种FIFO队列(即同步队列)来管理线程的阻塞状态,采用CAS方法更新状态(state)的值,从而实现线程的同步机制。

AQS的实现原理

状态(state)的表示和变更

AQS中同步状态的表示是通过一个整形变量(state)来实现的,这个整形变量保存了当前同步状态的信息,如锁的占用情况,信号量的数量等。

AQS使用volatile修饰的state变量来保证线程之间的可见性,当一个线程持有锁时,它会将state设置为一个非0的整数,当释放锁时,将state重新设置为0,其他线程可以通过判断state是否为0来确定锁是否被持有。

在Java中,要想实现线程之间的互斥和同步,就需要依赖于高效稳定的同步变量,而AQS通过使用volatile关键字保证了同步变量的可见性和共享性,使用CAS(Compare and Swap)操作实现了同步变量的原子操作。

同步队列(wait queue)

在AQS中,同步状态的线程都会被加入到一个双向链表中,该链表就是同步队列。同步队列可以分为两部分:一部分是已经获得同步状态的线程,在同步队列的前面;另一部分是等待获取同步状态的线程,在同步队列的后面。

同步队列中的节点是一个FIFO队列,每个节点都包含了一个Thread类型的引用,以及用于储存等待状态的数据结构(如ConditionObject),这些节点将竞争同步状态。

当一个节点(线程)需要获取同步状态但未能成功时,它会被封装成一个Node节点,并被插入到同步队列的末尾,线程会将自己挂起。当同步状态的线程(持有锁的线程)释放同步状态时,AQS会把同步队列中的第一个节点唤醒(即运行该节点中的线程),使其再次尝试获取同步状态。

同时需要注意同步队列中每个节点的状态,例如CANCELLED表示请求被取消,CONDITION表示处于等待条件状态,SIGNAL表示需要被唤醒,PROPAGATE表示需要向下传递唤醒信号等等。AQS中对节点状态的管理十分严格,对节点的操作都需要通过CAS操作保证线程之间的同步。

同步状态具体的实现

AQS中提供了两种方式去实现同步状态,分别是独占模式和共享模式。

独占模式(exclusive mode)

独占模式下,同一时刻只能有一个线程获取到同步状态。ReentrantLock、ReentrantReadWriteLock的实现都是基于独占模式的。

在独占模式下,AQS维护了一个关于是否占用的信息,并提供了acquire(获取)、release(释放)方法来操作同步状态。通过调用上述方法,在未获取到同步状态时,线程会被阻塞挂起,直至获取到同步状态为止。

共享模式(share mode)

在共享模式下,同一时刻可以有多个线程获取到同步状态。Semaphore、CountDownLatch的实现都是基于共享模式的。

在共享模式下,AQS使用类似于信号量的机制来管理同步状态。在信号量中,同时能够被允许的线程数量是有限的,当已经达到最大并发数时,其他等待执行的线程就需要等待。AQS中也有类似的机制,它使用两个变量来描述共享状态,一个代表当前状态(state),另一个代表正在等待的线程数(waiters)。

AQS提供了两个方法用于获取共享锁:tryAcquireShared(int arg)和tryAcquireSharedNanos(int arg, long nanosTimeout),当一个线程成功获取到共享锁时,其它线程也可以获取该锁而不是被阻塞。此外,AQS还提供了对同步状态的释放以及等待队列的维护等接口,使用上非常灵活。

应用场景

AQS作为Java并发包中的基础组件,为开发人员提供了一种简单、高效、稳定的机制来构建具有复杂同步需求的同步器。下面介绍几个常见的应用场景:

ReentrantLock

ReentrantLock是一个独占锁,即同一时刻只能有一个线程获取到锁。ReentrantLock的实现就是基于AQS的独占模式,它使用了一个整形变量state来表示锁的占用情况,当锁没有被占用时,state值为0,当锁被占用时,state值为1;当锁被重入时,也就是同一个线程再次获取锁时,state值会递增。ReentrantLock中的Condition也是基于AQS的同步机制来实现的。

Semaphore

Semaphore是一种计数器,用于控制同时访问某个资源的数量。Semaphore的实现也是基于AQS的共享锁机制,可用于请求池、线程池、数据库连接池等需要控制并发访问的场合。

CountDownLatch

CountDownLatch是一个计数器,用来让一个或多个线程等待一组操作完成。在一个或多个线程调用await()方法,等待计数器变为0之前,所有线程都会被阻塞。当计数器为0时,所有在await()方法上等待的线程都会被唤醒继续执行。CountDownLatch的实现也是基于AQS的共享锁机制。

总结

AQS是Java并发包中的一个基础组件,提供了构建各种同步器的框架。AQS使用FIFO等待队列、CAS操作、volatile关键字来实现同步机制,支持独占模式和共享模式两种同步状态,具有高效、稳定、灵活等优点。了解AQS的实现原理,开发者就可以更好地利用AQS构建自己的同步器,从而更好地保证程序的并发安全。

Java并发编程之AQS AQS是AbstractQueueSynchronizer是缩写,其意思就是抽象队列同步器。原理就是通过一个FIFO队列维护一个state同步状态值,只需要继承该抽象类重写对应的方法便可实现一套线程同步机制。AQS抽象类在java.util.concurrent.locks包下定义。如上图所示,AQS属于一个抽象类,主要是用来构建锁结构以及同步器的一个抽象类。AQS继承了AbstractOwnableSynchronizer,其作用为设置和获取独占锁的拥有者线程方法。 阅读详情

相关推荐

手把手教你用6轴IMU跑通LIO-SAM:参数配置与代码修改保姆级教程

本文提供了一套完整的6轴IMU适配LIO-SAM的解决方案,包括参数配置与代码修改的详细步骤。从理解6轴与9轴IMU的关键差异入手,逐步指导如何调整核心配置文件params.yaml、重构utility.h关键函数、优化mapOptimization.cpp的位姿融合逻辑,并给出编译验证与性能调优建议,帮助开发者快速实现6轴IMU在LIO-SAM中的稳定运行。

weixin_28717807的博客 356

Java并发-AQS及各种Lock锁的原理

 AQS是AbstractQueuedSynchronizer的简称。AQS提供了一种实现阻塞锁和一系列依赖FIFO等待队列的同步器的框架,如下图所示。AQS为一系列同步器依赖于一个单独的原子变量(state)的同步器提供了一个非常有用的基础。子类们必须定义改变state变量的protected方法,这些方法定义了state是如何被获取或释放的。鉴于此,本类中的其他方法执行所有的排队和阻塞机制。子...

phcgld1314的博客 608

HMC5883L磁力计在STM32F4上的I2C驱动与数据校准实战

本文详细介绍了HMC5883L磁力计在STM32F4平台上的I2C驱动开发与数据校准实战。通过解析寄存器配置、数据读取处理和椭圆拟合校准算法,帮助开发者实现精准的地磁测量,特别适用于无人机导航和机器人系统中的航向确定与陀螺仪漂移修正。

2y3u4i5o6p的博客 1036

JAVA多线程基础篇-AQS(AbstractQueuedSynchronizer)

AQS(AbstractQueuedSynchronizer)抽象队列同步器,是一种用来构建锁和同步器的框架。在JAVA,AQS是其它同步组件的基础框架(ReentrantLock、Semaphore、CountDownLatch、ReentrantReadWriteLock、SynchronusQueue等),它是JUC并发包中的核心组件。它不仅解决了在实现同步器时涉及的大量细节问题(自定义标准同步状态、FIFO同步队列等),还充分考虑了伸缩性,降低了上下文开销、提高了吞吐量。

qq_33479841的博客 3976

k最近邻算法——电影分类及案例详解

如图3-7所示,若将国际象棋棋盘放在二维直角坐标系中,格子的边长定义为1,坐标的x轴及y轴和棋盘方格平行,原点恰落在某一格的中心点,则王从一个位置走到其他位置需要的步数恰为二个位置的切比雪夫距离,因此切比雪夫距离也称为棋盘距离。关于这里的距离度量,这个电影分类的例子有2个特征,也就是2维的,可以使用我们高中学过的两点距离公式(两点距离公式其实就是欧氏距离在二维空间上的公式,也就是欧氏距离n的值为2的情况,欧氏距离也称为欧几里德距离)来计算距离,如图3-3所示。对数据进行归一化,避免量纲对计算距离的影响。

ZhShy 4552

WinForm轻松打造AntDesign现代化工具栏

摘要: 本文介绍如何在WinForm中利用AntdUI库实现AntDesign风格工具栏,包括安装配置、动态生成按钮/下拉菜单、布局优化及主题美化。通过AntButton、AntDropdown等控件结合事件绑定,可快速构建支持图标、工具提示、权限控制的现代化工具栏,并解决常见图标加载、布局错乱问题。最后提供代码示例与响应式设计技巧,助你打造高效美观的WinForm界面。 (字数:150)

java专栏 1589

Java知识学习13(AQS详解)

JavaSE

ldy007714的博客 3523

oracle ebs form 10g安装教程

这个窗口需要想想,你要安装的类型,不要盲目点击“下一步”,因为一旦Oracle安装后,重新安装之前,需要卸载Oracle干净才能重新安装,有时还会出现错误。到了该窗口后,需要耐心等待安装,安装到一大半后,自动弹出一个窗口,让我们选择Oracle安装第2部分磁盘的路径,继续安装,然后坐等安装结束。自定义安装Oracle根目录,点击“下一步”按钮后,耐心等待几秒钟,工具自动加载产品列表,加载完后,自动跳转到“选择安装类型”窗口。注:等待几秒钟后,关闭dos窗口,不必惊慌,自动调转到安装界面。

XIELIUHAI001的博客 473

Java 中 AQS 的实现原理

AQS(AbstractQueuedSynchronizer)是Java并发包中实现同步器的基础组件,广泛应用于锁的实现。AQS通过一个FIFO的双向队列管理被阻塞的线程,队列中的节点类型为Node,每个节点包含线程信息、前后节点指针以及等待状态。AQS通过维护一个状态变量state来控制同步状态,例如在ReentrantLock中,state表示锁的重入次数。当线程抢占锁失败时,会被封装成Node并加入AQS队列;当锁释放时,AQS会按照FIFO原则唤醒队列中的线程,并更新队列结构。

cijiancao的博客 955

电机控制中ADC采样时序的优化策略与实践

本文深入探讨了电机控制中ADC采样时序的优化策略与实践,重点分析了BLDC和FOC控制方案中的核心挑战与解决方案。通过硬件布局优化、软件滤波技术及动态时序补偿等方法,有效提升电流采样精度和系统稳定性,为电机控制系统的性能优化提供实用指导。

weixin_42519985的博客 386

Python爬虫实战:美团外卖商家数据抓取与分析

随着互联网技术的快速发展,外卖平台已成为人们日常生活中不可或缺的一部分。本文基于Python爬虫技术,使用最新的异步爬虫框架和反爬虫绕过技术,实现了对美团外卖平台商家信息与评分数据的自动化抓取。通过对抓取数据的清洗、存储和分析,为餐饮行业市场研究和商业决策提供数据支持。本文详细介绍了爬虫的设计思路、技术实现方案、数据处理方法以及可视化分析结果,为相关领域的研究者和开发者提供参考。关键词:Python爬虫;美团外卖;数据抓取;数据分析;异步爬虫。

2201_76125261的博客 1821

深入解析 Java AQS (AbstractQueuedSynchronizer) 的实现原理

AQS 提供了一套通用的同步框架,通过。等同步工具的核心实现都依赖于。管理线程的排队与唤醒,并支持。实现同步队列,每个节点是一个。,理解它的实现有助于深入掌握。最终会进入 AQS 的。等同步工具的工作原理。Java 并发包 (

weixin_43680337的博客 1063

【深度学习】Progressive Distillation for Fast Sampling of Diffusion Models

这种方法通过迭代地将一个需要较多步骤的模型(称为教师模型)蒸馏成一个需要较少步骤的学生模型,每次迭代都将采样步骤减半,直到达到所需的采样步骤数量。通过渐进式蒸馏,论文将原始需要8192步采样的模型成功蒸馏为只需4步采样就能取得接近的生成质量的新模型,大幅提高了扩散模型的推理效率。这篇论文提出了一种"渐进式蒸馏"(Progressive Distillation)的方法,来大幅降低用于生成对抗网络(GAN)的扩散模型(Diffusion Model)在推理阶段的采样步数,从而提高其推理效率。

q742971636的博客 1785

java之AQS的实现原理

AQS的内部实现的关键就是维护了一个先进先出的队列以及state状态变量。

yangzhanghui的专栏 3354

STM32F407中文手册

STM32f407中文手册 本参考手册面向应用开发人员,提供有关使用 STM32F405xx/07xx、STM32F415xx/17xx、 STM32F42xxx 和 STM32F43xxx 微控制器存储器与外设的完整信息。STM32F405xx/07xx、STM32F415xx/17xx、STM32F42xxx 和 STM32F43xxx 构成一个微 控制器系列,各产品具有不同的存储器大小、封装和外设。有关订购信息以及器件的机械与电气特性,请参见数据手册。有关 ARM Cortex™-M4F 内核的信息,请参见《Cortex™-M4F 技术参考手册》。

VC中sqlite的使用

在VC中对sqlite的使用,实现数据库大批数据的快速插入,读取数据库中的数据在ListCtrl中显示

Java中的CAS以及AQS实现原理

Java中的CAS实现原理 什么是CAS? 在计算机科学中,比较和交换(Conmpare And Swap)是用于实现多线程同步的原子指令。 它将内存位置的内容与给定值进行比较,只有在相同的情况下,将该内存位置的内容修改为新的给定值。 这是作为单个原子操作完成的。 原子性保证新值基于最新信息计算; 如果该值在同一时间被另一个线程更新,则写入将失败。 操作结果必须说明是否进行替换; 这可以通过一个简单的布尔响应(这个变体通常称为比较和设置),或通过返回从内存位置读取的值来完成。 JAVA中如何实现CAS操

老窦的博客 851

廖雪峰Python教程[完整版]

廖雪峰的python教程整理的,已经排好版了,而且还是完整的,适合小白

aqs java_Java中AQS基本实现原理

一、AQS概述AQS全名AbstractQueuedSynchronizer,意为抽象队列同步器,JUC(java.util.concurrent包)下面的Lock和其他一些并发工具类都是基于它来实现的。AQS维护了一个volatile的state和一个CLH(FIFO)双向队列。二、分析statestate是一个由volatile修饰的int变量,它的访问方式有三种:getState()setS...

weixin_31785177的博客 328

pscad IEEE标准系统搭建说明

pscad IEEE标准系统搭建说明,包含典型的IEEE 9节点、14节点、30节点、39节点和118节点系统。内含标准测试系统的原始数据和潮流结果。

Java中AQS的实现原理详解

本文深入解析Java并发包中AbstractQueuedSynchronizer(AQS)的实现原理,涵盖同步状态、CLH队列、独占与共享模式等核心机制。

qq_51481690的博客 759

JAVA并发编程-AQS底层实现原理及应用(一)

Java中的大部分同步类(CountDownLatch,Semaphore,CyclicBarrier、ReentrantLock等)都是基于AbstractQueuedSynchronizer(简称为AQS)实现的。AQS是一种提供了原子式管理同步状态、阻塞和唤醒线程功能以及队列模型的简单框架。本篇不讲述包含共享锁和Condition Queue的部分。//加锁//设置state 0没有线程持有锁,1有线程持有锁//释放锁//创建condition//模板方法。

qq_51059003的博客 1748

Java中的锁及AQS实现原理

本文整个体系和内容参考了《Java并发编程的艺术》和JDK8的JUC源码,JUC源码的注解写的还是很详细的。 Lock接口 锁是用来控制多个线程访问共享资源的方式,一般来说,一个锁能够防止多个线程同时访问共享资源(但是有些锁可以允许多个线程并发的访问共享资源,比如读写锁)。在Lock接口出现之前,Java程序是靠synchronized关键字实现锁功能的,而Java 5之后,并发包中新增了Lock...

TJtulong的博客 2730

深入理解 Java AQS 原理与 ReentrantLock 实现

AbstractQueuedSynchronizer(简称 AQS)是 Java 并发包(java.util.concurrent)中最核心的基础组件之一,它为 Java 中的大多数同步类(如 ReentrantLock、Semaphore、CountDownLatch 等)提供了一个通用的框架。理解 AQS 的工作原理对于深入掌握 Java 并发编程至关重要。AQS 的作用是解决同步器的实现问题,它将复杂的同步器实现分解为简单的框架方法,开发者只需要实现少量特定的方法就能快速构建出可靠的同步器。

weixin_36856852的博客 63

Java并发包AQS实现原理?

AQS(AbstractQueuedSynchronizer)是Java并发包中锁和同步器的核心基础,支持独占锁和共享锁两种模型。其核心原理包括状态(state)和CLH队列,通过CAS操作和模板方法模式实现高性能并发控制。AQS的核心方法如acquire、release等,用于资源的获取和释放,而具体的获取和释放逻辑由子类实现。AQS的加锁流程涉及尝试获取锁、加入等待队列、线程阻塞和唤醒等步骤,确保公平性和避免线程饿死。AQS广泛应用于ReentrantLock、Semaphore、CountDownLa

weixin_46072507的博客 655

并发编程 | Java中AQS的基本实现原理及简单使用

本文将介绍Java中AQS的基本原理,并基于AQS实现自定义阻塞式不可重入锁,以此来演示AQS的使用。

字节幺零二四的博客 1139

AQS框架下的Java锁实现原理

综上所述,AQS框架下的Java锁实现原理主要涉及到对象锁的基本概念和AQS框架的实现方式。对象锁是Java锁的基本实现方式,它通过对象的锁机制实现对共享资源的保护。当一个线程需要访问某个对象时,该线程会获取该对象的锁,只有拥有该锁的线程才能对该对象进行操作。Java锁是实现并发控制的一种重要手段,它通过在Java程序中实现对象的锁机制,实现对共享资源的保护。(3)考虑并发控制级别:在使用AQS框架下的Java锁时,需要根据实际需求选择合适的并发控制级别,以避免过度的并发控制和资源浪费。

searchboy2025的博客 38
上一篇: Java中的synchronized关键字原理详解
下一篇: 云计算:未来信息技术基础设施的首选
JavaWizard-M
博客等级 码龄6年 3159粉丝 148原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值