AQS简简单单过一遍

从养虾到退坑:OpenClaw 卸载不留残留,一步到位 文章摘要: 本文提供OpenClaw软件的完整卸载指南,适用于Windows、macOS和Linux系统。内容包含卸载前的数据备份步骤(配置文件、日志、插件列表),以及详细的卸载脚本。Windows版通过批处理文件删除程序文件、注册表项和环境变量;macOS/Linux版则提供shell脚本,涵盖服务停止、软件包卸载、配置清理等步骤。特别强调要删除所有用户数据(包括多用户环境),确保系统无残留。文末建议重启计算机以使更改生效,实现"一步到位"的彻底卸载。 阅读详情

前言

回顾前面:

只有光头才能变强!

本来我是打算在这章节中写Lock的子类实现的,但看到了AQS的这么一个概念,可以说Lock的子类实现都是基于AQS的。

AQS我在面试题中也见过他的身影,但一直不知道是什么东西。所以本篇我就来讲讲AQS这个玩意吧,至少知道它的概念是什么,对吧~

那么接下来我们就开始吧~

一、AQS是什么?

首先我们来普及一下juc是什么:juc其实就是包的缩写(java.util.concurrnt)

  • 不要被人家唬到了,以为juc是什么一个牛逼的东西。其实指的是包而已~

我们可以发现lock包下有三个抽象的类:

  • AbstractOwnableSynchronizer
  • AbstractQueuedLongSynchronizer
  • AbstractQueuedSynchronizer

通常地:AbstractQueuedSynchronizer简称为AQS

我们Lock之类的两个常见的锁都是基于它来实现的:

那么我们来看看AbstractQueuedSynchronizer到底是什么,看一个类是干什么的最快途径就是看它的顶部注释

通读了一遍,可以总结出以下比较关键的信息:

  • AQS其实就是一个可以给我们实现锁的框架
  • 内部实现的关键是:先进先出的队列、state状态
  • 定义了内部类ConditionObject
  • 拥有两种线程模式
    • 独占模式
    • 共享模式
  • 在LOCK包中的相关锁(常用的有ReentrantLock、 ReadWriteLock)都是基于AQS来构建
  • 一般我们叫AQS为同步器

二、简单看看AQS

上面也提到了AQS里边最重要的是状态和队列,我们接下来就看看其源码是怎么样的…

2.1同步状态

使用volatile修饰实现线程可见性:

修改state状态值时使用CAS算法来实现:

2.2先进先出队列

这个队列被称为:CLH队列(三个名字组成),是一个双向队列

看看它队列源码的组成:


    static final class Node {

        // 共享
        static final Node SHARED = new Node();

        // 独占
        static final Node EXCLUSIVE = null;

        // 线程被取消了
        static final int CANCELLED =  1;

        // 后继线程需要唤醒
        static final int SIGNAL    = -1;

        // 等待condition唤醒
        static final int CONDITION = -2;

        // 共享式同步状态获取将会无条件地传播下去(没看懂)
        static final int PROPAGATE = -3;


        // 初始为0,状态是上面的几种
        volatile int waitStatus;

        // 前置节点
        volatile Node prev;

        // 后继节点
        volatile Node next;


        volatile Thread thread;


        Node nextWaiter;

        final boolean isShared() {
            return nextWaiter == SHARED;
        }


        final Node predecessor() throws NullPointerException {
            Node p = prev;
            if (p == null)
                throw new NullPointerException();
            else
                return p;
        }

        Node() {    // Used to establish initial head or SHARED marker
        }

        Node(Thread thread, Node mode) {     // Used by addWaiter
            this.nextWaiter = mode;
            this.thread = thread;
        }

        Node(Thread thread, int waitStatus) { // Used by Condition
            this.waitStatus = waitStatus;
            this.thread = thread;
        }
    }

2.3acquire方法

获取独占锁的过程就是在acquire定义的,该方法用到了模板设计模式,由子类实现的~

过程:acquire(int)尝试获取资源,如果获取失败,将线程插入等待队列。插入等待队列后,acquire(int)并没有放弃获取资源,而是根据前置节点状态状态判断是否应该继续获取资源,如果前置节点是头结点,继续尝试获取资源,如果前置节点是SIGNAL状态,就中断当前线程,否则继续尝试获取资源。直到当前线程被park()或者获取到资源,acquire(int)结束。

来源:

2.4release方法

释放独占锁的过程就是在acquire定义的,该方法也用到了模板设计模式,由子类实现的~

过程:首先调用子类的tryRelease()方法释放锁,然后唤醒后继节点,在唤醒的过程中,需要判断后继节点是否满足情况,如果后继节点不为且不是作废状态,则唤醒这个后继节点,否则从tail节点向前寻找合适的节点,如果找到,则唤醒.

来源:

三、最后

总结一下AQS到底是什么吧:

  • juc包中很多可阻塞的类都是基于AQS构建的
    • AQS可以说是一个给予实现同步锁、同步器的一个框架,很多实现类都在它的的基础上构建的
  • 在AQS中实现了对等待队列的默认实现,子类只要重写部分的代码即可实现(大量用到了模板代码)

有兴趣的同学可去看源码和下面的链接继续学习,我这里就不讲述了。简简单单把AQS过一遍~

明天就看Lock显式锁实现咯~~~

参考资料:

如果文章有错的地方欢迎指正,大家互相交流。习惯在微信看技术文章,想要获取更多的Java资源的同学,可以关注微信公众号:Java3y。为了大家方便,刚新建了一下qq群:742919422,大家也可以去交流交流。谢谢支持了!希望能多介绍给其他有需要的朋友

文章的目录导航:

反应动力学仿真软件:Kintecus_(4).用户界面及操作指南 在 Kintecus 中,反应方程的定义非常灵活。您可以定义简单的一阶反应、复杂的多步反应以及不同类型的反应机制。 阅读详情

相关推荐

冗余位技术在SAR ADC中的动态误差恢复机制解析

本文深入解析了冗余位技术在SAR ADC中的动态误差恢复机制,详细介绍了其基本概念、动态误差产生原因及冗余位的容错空间设计、时序松弛策略和数字校正算法。通过实际电路设计案例和数学建模,展示了冗余位技术如何显著提升ADC的精度和能效比,同时探讨了未来发展方向。

weixin_28335283的博客 975

【Java并发编程】之 AQS

AQS 介绍 AQS的全称为(AbstractQueuedSynchronizer),这个类在java.util.concurrent.locks包下面。 AQS是一个用来构建锁和同步器的框架,使用AQS能简单且高效地构造出应用广泛的大量的同步器,比如我们提到的ReentrantLock,Semaphore,其他的诸如ReentrantReadWriteLock,SynchronousQueue,FutureTask等等皆是基于AQS的。当然,我们自己也能利用AQS非常轻松容易地构造出符合我们自己需求的.

王廷云的博客 1288

全志T113 Tina5.0开发:(零)源码下载&修改调试串口

本文章主要作为自己的笔记,如有错误欢迎指出$ repo start product-da-t113-tina-stable --all # 全部下载完成之后,创建分支运行过程可能会出现版本问题;rm -rf .repo //先删除试试( 我安装的是3.6版本)

u014428915的博客 1166

AQS 工作原理

而且tryRelease()的返回值代表着该线程是否已经完成资源的释放,因此在自定义同步器的tryRelease()时,需要明确这条件,当已经彻底释放资源(state=0),要返回true,否则返回false。unparkSuccessor用unpark()唤醒等待队列中最前驱的那个未放弃线程,此线程并不一定是当前节点的next节点,而是下一个可以用来唤醒的线程,如果这个节点存在,调用unpark()方法唤醒。如果获取到资源,线程直接返回,否则进入等待队列,直到获取到资源为止,且整个过程忽略中断的影响。

worn_xiao的博客 8999

Silvaco Athena实战:从零搭建MOSFET工艺仿真流程(附mos1ex03完整代码解析)

本文详细介绍了使用Silvaco Athena从零搭建MOSFET工艺仿真的全流程,包括环境配置、核心工艺步骤、器件成型及参数提取等关键环节。通过mos1ex03案例的完整代码解析,帮助读者掌握网格划分、氧化层生长、离子注入等实战技巧,提升半导体工艺仿真能力。

weixin_42648844的博客 406

从碰撞电离到雪崩击穿:Sentaurus仿真中的模型选择与验证艺术

本文深入探讨了Sentaurus TCAD中雪崩击穿模型的选取与验证方法,特别关注平行平面结的仿真实践。通过对比Chynoweth、van Overstraeten等主流模型的适用场景与精度差异,结合具体案例展示了从几何建模到边界条件设定的完整验证流程,并针对非理想因素提供了有效的补偿技术,助力工程师提升器件仿真的准确性与可靠性。

weixin_29074295的博客 592

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

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

phcgld1314的博客 608

逆向攻防世界CTF系列40-ReverseMe-120

注意sub_401000main中只传了两个参数,但是跟进后发现四个(可能是隐式传递,放在寄存器里传递了),调试发现a4是输入长度,与最终的you_know_how_to_remove_junk_code比较的是v12(但是并没有被传入),开始怀疑是不是隐式传递了。_mm_xor_si128用于计算128位(16字节)的按位异或,然后通过v14控制循环结束的条件,可以看到v14增长的步长为16,而且通过上面得到的flag值解码得到的字符串为32个字节大小,正好是16的整数倍。

LH1013886337的博客 1410

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

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

qq_33479841的博客 3976

解决anaconda占用C盘空间过多问题

anaconda就算安装在其他盘,默认会把索引、锁定文件、压缩包等都放到系统盘(C盘),我用了两年,占用30GB。 1. 卸载不用的虚拟环境 查看已安装的虚拟环境 conda env list 卸载不用的、过期的虚拟环境 conda remove -n (要卸载的环境的名字) --all 2. 删除索引缓存、锁定文件、未使用过的包和tar包 conda clean -a 清理完之后,删除了15GB,还剩15GB,舒服了 ...

沉迷单车的追风少年 3万+

SAP MM模块后续借记、后续贷记、贷方凭证简介

在SAP系统中,后续借记、后续贷记和贷方凭证是处理供应商发票、采购和付款过程中常见的财务交易。

我小时候很黑的博客 3270

AQS实现原理

AQS中维护了一个volatile int state(共享资源)和一个CLH队列。当state=1时代表当前对象锁已经被占用,其他线程来加锁时则会失败,失败的线程被放入一个FIFO的等待队列中,然后会被UNSAFE.park()操作挂起,等待已经获得锁的线程释放锁才能被唤醒。 我们拿具体场景来分析,假设同时有三个线程并发抢占锁,此时线程一抢占成功,线程二、三抢占失败,具体流程如下: 此时AQS内部数据结构为: 上图可以看到等待队列中的节点Node是一个双向链表,这里SIGNAL是No..

summer_fish的专栏 5543

DeepSeek+Dify之一安装部署

DeepSeek添加知识库

yilvyangguang520的博客 1544

Lock简介与初识AQS

文章目录concurrent包的结构层次Lock简介Lock接口API初识AQSAQS的模板方法设计模式一个例子 concurrent包的结构层次 在针对并发编程中,Doug Lea大师为我们提供了大量实用,高性能的工具类,针对这些代码进行研究会让我们队并发编程的掌握更加透彻也会大大提升我们队并发编程技术的热爱。这些代码在java.util.concurrent包下。如下图,即为concurren...

ThinkWon的博客 1万+

IMSL CNL 7.0.0 (x86-64)Crack

IMSL CNL 7.0.0 (x86-64)Crack intel的算法库破解文件,这是C++版本的破解文件

TMS_WebGMaps_1.9.8.0_Full_Source

TMS_WebGMaps_1.9.8.0_Full_Source 全源码 delphi cbuilder

JavaSE中AQS详解

在Java中,AQS是指AbstractQueuedSynchronizer,是Java并发编程中的一个关键类。AQS是用来构建同步器(Synchronizer)的框架,它提供了一种实现线程安全性和管理等待线程的机制。AQS基于一个FIFO(先进先出)的等待队列,可以被子类扩展来实现各种同步器,如ReentrantLock、CountDownLatch、Semaphore等。AQS通过定义了若干个方法来管理线程的获取和释放资源,其中最为重要的方法是acquire()和release()。

mercedes_benz 312

Statistics and Machine Learning Toolbox

Statistics and Machine Learning Toolbox(带书签),MATLAB统计学习工具

AQS详解

前言:之前AQS、ReentrantLock、CountLatchDown大概原理都看懂了,面试的时候一问能说个大概,感觉这样也就行了,跟背课文一样背源码也没什么意思,但是根据被拒的情况可能只说个大概不能满足面试官,今天结合源码好好看一遍,适合有一定基础的同学。 参考: https://blog.youkuaiyun.com/u013728021/article/details/87358517 https://www.cnblogs.com/waterystone/p/4920797.html 第一章 AQS

仰望星空 1899

win10 跳过U8环境检测的IE WebControls.rar

win10 安装u8的时候 提示IE WebControls 不通过,这个工具可以欺骗u8的检查。 跳过U8环境检测的IE WebControls。提示导入失败后,重新检测通过。

【深入AQS原理】我画了35张图就是为了让你深入 AQS

谈到并发,我们不得不说AQS(AbstractQueuedSynchronizer),所谓的AQS即是抽象的队列式的同步器,内部定义了很多锁相关的方法,我们熟知的ReentrantLock、ReentrantReadWriteLock、CountDownLatch、Semaphore等都是基于AQS来实现的。

weixin_44837153的博客 839

Java并发编程-AQS

AQS既AbstractQueuedSynchronizer队列同步器 ,**是用来构建锁或者其他同步组件的基础框架**,它使用了一个 int 成员变量表示同步状态,通过内置的 FIFO 队列来完成资源获取线程的排队工作。

千月落 8757

最硬核的AQS解析,你啃的下来么?

AQS是什么? 很多初学者在刚接触AQS的时候,甚至可能在学习了一遍之后,还是觉得这个知识点有些虚无缥缈。 因为太多太多的文章博客,上来就用AQS来讲ReentrantLock了,然后一顿学习后,诶?这和AQS有什么关系?首先,我们还是一步一步来由浅入深的去了解AQS。 让我们穿越到过去,在JDK1.5以前只有synchronized同步锁,这个锁在那个时代是真的low。功能十分的局限,比如我想完成一个锁中的分组唤醒(Condition),锁的阻塞线程可打断,锁的公平功能等等。此外,速度也慢的一塌糊涂

weixin_47184173的博客 1253

实际场景解读AQS读写锁ReentrantReadWriteLock

前面讲了什么是AQS.并且基于Reentrantlock已经看了一部分AQS方法. AQS是什么?基于ReentrantLock解密! 但是其实真实项目中一般使用ReetrantLock,一般都是synchronized. 因为在jdk1.6之后,synchronized底层实现里面,里面做了一些计数器的维护,加锁释放锁,CAS啊.都能实现ReentrantLock一样的效果.而且使用起来相对简单. 另外读写锁ReentrantReadWriteLock其实也挺常用的 下面就接着看对于Reentra..

qq_25933841的博客 1908

说说ReentrantLock,ReentrantLock底层是AQS,AQS的原理

概念: ReentrantLock(可重入锁):一个线程已经获得了锁,其内部还可以多次申请该锁成功(即不需要再次抢占锁,直接增加重入的次数)。ReentrantLock并没有直接继承AQS类,而是通过内部类来继承AQS类的,这样自己的实现功能,自己用。默认NonfairSync非公平锁。 公平锁的实现机理在于每次有线程来抢占锁的时候,都会检查一遍有没有等待队列(FIFO双端队列),相对于非公平锁lock()少了插队部分(即少了CAS尝试将state从0设为1,进而获得锁的过程)。(2次插队) 原理图:

m0_37840000的博客 555

深入理解 JUC 的AQS 内部核心结构

AbstractQueuedSynchronizer:AQS,抽象队列同步器。主要是为了解决竞争的问题。AQS使用一个volatile修饰的int类型的成员变量state来表示同步状态,1表示其他线程持有锁,0表示锁未被其他线程持有。之所以使用volatile是因为需要保证state成员变量在多线程之间保持可见性,修改state的时候需要使用CAS机制来确保原子性。如果共享资源被占用,就需要一定的阻塞等待唤醒机制来保证锁分配。

sjisbbeksudh的博客 717

学习笔记:AQS

序言 好久没有写文章了,最近太懒了哈哈,今天督促自己写一下AQS的学习笔记吧,因为前段时间刚温习了一遍。 AQS AQS全称是:AbstractQueuedSynchronizer(抽象的队列同步器),它隶属于我们的JUC包,可以说AQS就是并发类的基类/规范了,很多类都是基于AQS实现的:lock锁,CountDownLatch,CyclicBarrier,Semaphore了。 AQS的工作原理:当有线程来获取共享资源时,如果共享资源处于空闲状态,那么该线程就设置为工作线程,共享资源设为锁定状态,如果线

guojunjiang12345的博客 803

手撕AQS源码第三弹 --AQS加锁解锁原理

AQS加锁解锁原理 这是网上引用的一张流程图,讲的非常明白,但是对于没有扒过源码的小伙伴而言,有点困难了。比如SIGNAL,方法没有加注释,就上传了这个一个图也好几百访问量,我裂开了。 首先讲加锁的流程之前,先把相关的方法,变量简单讲一遍 相关变量 private transient volatile Node head; private transient volatile Node tail; private volatile int state; 解释: 我们的队列由Node组成,每个Node

程序员小章的博客 1672
上一篇: Java锁机制了解一下
下一篇: Lock锁子类了解一下
Java3y
Java3y 领域专家: 后端开发技术领域 领域专家: 后端开发技术领域
博客等级 码龄9年 1万+粉丝 509原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值