关于AQS中的enq方法的理解

Java并发:深入浅出AQS之独占锁模式源码分析,狂神说java进阶路线 Node .EXCLUSIVE), arg)) selfInterrupt(); } 代码虽然短,但包含的逻辑却很多,一步一步看下: 1、首先是调用开发人员自己实现的 tryAcquire() 方法尝试获取锁资源,如果成功则整个 acquire()方法执行完毕,即当前线程获得锁资源,可以进入临界区。 2、如果获取锁失败,则开始进入后面的逻辑,首先是 addWaiter(Node.EXCLUSIVE)方法。来看下这个方法的源码实现 addWaiter(Node) 此方法用于将当前线程加入到等待队列的队尾,并返 阅读详情

自己太笨了,总感觉有点绕,就整理下吧~

private Node enq(final Node node) {
	//自旋锁
    for (;;) {
        //tail默认就是null
        Node t = tail;
        if (t == null) { // Must initialize
            //因为tail默认是null,所以首次一定会进来
            //compareAndSetHead在下面
            //也就是首次一定会把一个新的node设置为head
            if (compareAndSetHead(new Node()))
                //tail=head=new Node()
                tail = head;
            //到这里就是tail和head都会指向new Node
        } else {
            //第二次一定进入else发
            //假如此时进入了一个线程A,这个A已经被封装成了node传进来
            //当前的node的pre指向t,也就是tail,也就是刚才创建的Node,
            //因为第一行就定义了Node t = tail,而t=head=node
            node.prev = t;
            //这里看下面的compareAndSetTail方法
            //把tail节点赋值为新传入的node(Thread A),赋值操作就相当于指向
            if (compareAndSetTail(t, node)) {
                //这里的t指的是原来的tail节点,tail指向一开始的new Node
                //所以就是new Node的next指向新传入的node(Thread A)
                t.next = node;
                return t;
            }
        }
    }
}


private final boolean compareAndSetHead(Node update) {
    //当前的head字段,和null值比对,默认是null,所以相等,所以赋值为update,也就是new node()
    return unsafe.compareAndSwapObject(this, headOffset, null, update);
}


private final boolean compareAndSetTail(Node expect, Node update) {
    //当前的tail字段和期望值exepct,即t进行比较,一定是相等的啊,以为t=tail么,所以更新赋值为update,
    //即新传进来的node(Thread A)
    return unsafe.compareAndSwapObject(this, tailOffset, expect, update);
}

第一次一定是进入if

在这里插入图片描述

当有新的线程进入的时候,进入else(其实没有新的线程进入还是要进入else的),红色的是else所做的操作

在这里插入图片描述

总结:

这里面head和tail都是一个node,但是这里我理解为一个类似于指针的东西,它们存在的意义也是为了维持这个双向的链表,没有实际的意义,包括prev和next也是。

还是挺绕的,感觉没必要理解这么透彻,主要思想就是

第一次进来的时候创建这个双向链表的空节点,后面传入新的节点的时候,开始往双向链表后面添加新的节点,而head和tail永远指向第一个和最后一个,中间都是一些切换指针(我这里暂且理解为指针吧,也就是赋值操作,比如tail和head的赋值,prev和next的赋值。)

for(;;)是一个自旋锁,为了不停的去尝试添加节点,但是可能存在并发问题,所以通过cas的方式,添加,可能上次被线程a抢占先机,这次自己还是要去尝试,如何进行不断的尝试?所以通过自旋锁解决,当然如果添加成果最后会通过return跳出自旋锁。

个人认为这个自旋锁和cas的操作用的很厉害,值得学习!
仔细想想为什么这么设计?
因为当前的这个compareAndSetTail和compareAndSetHead,这两个操作,简单说就是为了切换指针指向,简单说就是一“操作”,任何操作,因为在操作系统中,虽然我们目前在解决并发问题,但是也是存在并发问题的,对于这个“操作来说”。所以我们可以选择加锁,也可以选择这种cas自旋锁的方式,因为这个操作可能是很快的,因为可能同时又一万个线程都被阻塞了(极端一点的情况),这个时候,会有很多的切换指针的这个“操作”,反复的加悲观锁的话,没有cas这种乐观锁好。简单总结下,就是这种cas自旋锁的方式能提升性能。

以上全是我的个人理解,可能存在很大的问题,希望没有误导到你,如果有问题还希望您及时指出。

基于AQS驱动的ReentrantLock公平锁和非公平锁实现原理解析 本文通过代码调试分析了ReentrantLock的可重入特性及其底层AQS实现机制。重点解析了: 通过state变量记录锁重入次数,加锁时CAS递增,解锁时递减; 以NonfairSync为例展示了非公平锁的直接抢锁逻辑; 揭示了AQS通过volatile state变量和CAS操作实现同步状态管理; 完整跟踪了lock()/unlock()方法的执行流程,说明AQS是JUC锁工具的底层基础。 阅读详情

相关推荐

华为无线AP+AC(ensp)

VLAN 100--192.168.100.0/24为AP的管理IP地址VLAN10--192.168.10.0/24为无线用户获取的IP地址在DHCP Server(LSW3)上查看地址分配情况。

abcdlalal的博客 1万+

关于AQS中enq( )方法CAS操作的疑惑

private Node enq(final Node node) { for (;;) { Node t = tail; //如果队列为空则新建头结点 if (t == null) { // Must initialize if (compareAndSetHead(new Node()))//这个操作是新建队列 //将tail指向头结点 tail = head; } else { //1.将新节点的前置指针指向链表尾部 node.prev = t; //2.通过CAS...

进三步的博客 720

手把手教你用Siemens EDA破解工具搞定PADs VX2.7安装与卡死问题

本文详细介绍了如何使用Siemens EDA工具解决PADs VX2.7的安装与卡死问题。从License配置到性能调优,提供全面的解决方案,帮助工程师高效完成电子设计自动化任务。特别针对常见的卡顿现象,给出了输入法兼容性调整、图形性能优化等实用技巧。

k8l9m0n的博客 548

Java并发编程知识点总结(八)——AQS源码分析之独占锁

(一)、AQS概述 AbstractQueuedSynchronizer简称AQS,它是java.util.concurrent包中,它提供了一套完整的同步编程框架。我们常用的ReentrantLock、CountDownLatch都是基于AQS实现的。 AQS的实现分为两种形式,一种是独占锁,另一种则是共享锁。 独占锁:每次只能有一个线程持有锁。我们比较熟悉的ReentrantLock就是通过...

热爱永不过时! 634

【实战揭秘】高胜率集合竞价抓涨停策略:融合MACD背离与斐波那契的量化模型

本文揭秘了一种高胜率集合竞价抓涨停策略,融合MACD背离与斐波那契数列的量化模型。通过量能异动、技术形态突破和资金共识形成的交叉验证,该策略在实盘中表现出色。文章详细解析了MACD背离的量化实现细节、斐波那契数列的实战应用,以及策略的量化建模过程,帮助投资者提升交易胜率。

herb5的博客 1549

自适应滤波算法综述

自适应滤波算法综述

xdzhujy的博客 5万+

并发编程(七)之AQS

概述 队列同步器 AbstractQueuedSynchronizer(以下简称AQS),是用来构建锁或者其他同步组件的基础框架,它使用了一个 int 成员变量表示同步状 态,通过内置的 FIFO 队列来完成资源获取线程的排队工作。并发包的大师(DougLea)期望它能够成为实现大部分同步需求的基础。 AQS使用方式和其中的设计模式 AQS 的主要使用方式是继承,子类通过继承 AQS 并实现它的抽象方法来管理同步状态,在 AQS 里由一个 int 型的 state 来代表这个状态,在抽象方法的实 现过程中免

个人站点:javatv.net 525

Windows 11最新WDK安装避坑指南:从Visual Studio配置到KMDF驱动开发

本文提供了在Windows 11系统上进行KMDF驱动开发的完整环境搭建与实战指南。针对最新WDK与Visual Studio的配置变化,详细解析了从独立安装WDK/SDK、创建首个KMDF驱动项目,到编译排错、部署调试的全流程,帮助开发者高效避坑,顺利开启Windows内核开发。

weixin_29302047的博客 525

关于AQS

了解的不多 写博客主要是为了便于自己理解和记忆 内容多数为各个博客上面总结的 再加上一点自己的理解 见谅 什么是AQS? AbstractQueuedSynchronizer 抽象队列同步器 是一套多线程访问共享资源的框架 注意是框架 不是具体的实现 原理:内部依赖了FIFO双向队列 如果当前线程获取失败 AQS会将该线程以及等待状态等信息构造成一个Node,将其加入同步队列的尾部,同时阻塞当前线程,当同步状态释放时,唤醒队列的头节点 具体的实现有什么? 如CountDownLatch Reen

weixin_44575276的博客 234

使用 Python 爬取网易云音乐歌单数据(完整教程)

随着在线音乐平台的普及,网易云音乐(NetEase Cloud Music)凭借其个性化的推荐算法和丰富的用户互动,吸引了大量用户。网易云音乐的歌单中包含了丰富的音乐数据,包括歌曲名、歌手、专辑、播放量、评论数等信息。通过爬取这些数据,可以对音乐流行趋势进行分析,挖掘音乐推荐策略,甚至训练个性化推荐模型。网易云音乐的 API 并未官方开放,但开发者通过抓包和逆向分析,找到了若干可用接口。✅ 数据清洗与存储(CSV/数据库)✅ 网易云音乐 API 接口分析。✅ 网易云音乐接口解析。✅ 同步与异步爬取实现。

2201_76125261的博客 1371

构建一个基于Simulink的LC滤波器仿真模型

需求分析LC滤波器(Inductor-Capacitor Filter)是一种常见的无源滤波器,广泛应用于电力电子、通信、音频处理等领域。其主要作用是平滑输入信号中的高频谐波成分,保留低频或直流成分,从而提高输出信号的质量。在电力电子系统中,LC滤波器常用于逆变器、整流器等设备的输出端,以减少开关噪声和电磁干扰(EMI),确保输出电压和电流的稳定性。本项目将基于Simulink平台,开发一个完整的LC滤波器仿真模型,涵盖从电源输入到滤波输出的整个过程,并通过PI控制器实现对滤波效果的闭环控制。

MHD0815的博客 733

AQS同步器

AQS(同步器) AQS是AbstractQueuedSynchronizer的简称,是一个用来构建锁和同步器的框架。 原理概述 AQS核心思想是,如果被请求的共享资源空闲,则将当前请求资源的线程设置为有效的工作线程,并且将共享资源设置为锁定状态。如果被请求的共享资源被占用,那么就需要一套线程阻塞等待以及被唤醒时锁分配的机制,这个机制AQS是用CLH队列锁实现的,即将暂时获取不到锁的线程加入到队列...

java小菜鸡成长之路 310

PCL 基于法线微分(DoN)的点云分割【2026最新版】

基于法线微分的分割。博客长期更新,本文最新更新时间为:2026年5月10日。

点云侠的博客 39万+

java AQS源码学习

java AQS源码学习AbstractQueuedSynchronizerNode一些变量和方法addWaiter和enqacquire以及相关方法release后记 AbstractQueuedSynchronizer AbstractQueuedSynchronizer抽象队列同步器, 简称AQS, 只有读懂了AQS的源码才能看懂ReentrantLock可重入锁是如何实现的 Node no...

Cia_zibo的博客 576

IEM模型,地表粗糙度模拟

利用微波反演土壤水分时候,利用IEM模型可以实现对随机地表的模拟

Data-Structures-and-Algorithm-Analysis-in-Java.pdf

作者: Weiss, Mark A. 出版社: Addison Wesley Data Structures and Algorithm Analysis in Java is an “advanced algorithms” book that fits between traditional CS2 and Algorithms Analysis courses. In the old ACM Curriculum Guidelines, this course was known as CS7. This text is for readers who want to learn good programming and algorithm analysis skills simultaneously so that they can develop such programs with the maximum amo...

Java AQS 实现——数据组织

引言 从本篇文章开始,我们将介绍 Java AQS 的实现方式,本文先介绍 AQS 的内部数据是如何组织的,后面的文章中再分别介绍 AQS 的各个部门实现。 AQS 通过前面的介绍,大家一定看出来了,上述的各种类型的锁和一些线程控制接口(CountDownLatch 等),最终都是通过 AQS 来实现的,不同之处只在于 tryAcquire 等抽象函数如何实现。从这个角度来看,AQS(AbstractQueuedSynchronizer) 这个基类设计的真的很不错,能够包容各种同步控制方案,并提供了必须的

贝克街的流浪猫 305

SIMATIC S7-1200, S7-1500 PID 控制[手册]

SIMATIC S7-1200, S7-1500 PID 控制[手册]

JUC锁 Locks核心类,AQS原理,通过源码进行学习深入了解1

概述 AbstractQueuedSynchronizer抽象类(以下简称AQS)是整个java.util.concurrent包的核心。在JDK1.5时,Doug Lea引入了J.U.C包,该包中的大多数同步器都是基于AQS来构建的。AQS框架提供了一套通用的机制来管理同步状态(synchronization state)、阻塞/唤醒线程、管理等待队列。 AQS核心思想 AQS核心思想是,如果被请求的共享资源空闲,则将当前请求资源的线程设置为有效的工作线程,并且将共享资源设置为锁定状态。如果被请求的共享资

qq_30921153的博客 348

假人有限元模型

假人模型,车辆碰撞假人有限元模型,适合做乘员安全的研究者利用

014-从0到1带你深入并发编程:深入剖析AQS条件队列:signal()如何实现节点从等待到同步的精准转移

本文深入分析了Java多线程编程中条件队列与同步队列的协同工作机制,重点剖析了节点从条件队列转移到同步队列的关键过程。文章详细解读了doSignal方法的遍历策略、transferToSyncQueue的原子性保证、enq方法的线程安全实现,以及等待状态的生命周期管理。通过CAS操作和状态流转的设计,AQS框架实现了高效可靠的线程通信机制。文章还探讨了"延迟唤醒"策略的性能优势,并总结了状态管理、原子操作等并发编程的核心要素,为开发者理解底层机制和优化并发性能提供了重要参考。

源码获取 | 运行部署 | 定制二开修改,如果回复不及时请耐心等待,请见谅。 1010

AQS源码解析

AQS(AbstractQueuedSynchronizer)是一个用于构建锁和同步器的框架,采用分工思想:开发者只需定义资源状态(state)和获取/释放逻辑(tryAcquire/tryRelease),AQS则负责线程排队、阻塞唤醒等复杂操作。其核心分为模板方法(需子类实现)和框架方法(可直接调用),支持独占和共享两种资源访问模式。内部类Node构成等待队列,ConditionObject实现精准线程通信。通过这种分工,AQS简化了同步器的实现,开发者只需关注核心逻辑,框架处理其余细节。

weixin_46028606的博客 1138

深入理解AQS(AbstractQueuedSynchronizer)

AbstractQueuedSynchronizer(AQS)是JDK中实现并发编程的核心,平时我们工作中经常用到的ReentrantLock,CountDownLatch等都是基于它来实现的。 AQS类中维护了一个双向链表(FIFO队列), 如下图所示: 队列中的每个元素都用一个Node表示,我们可以看到,Node类中有几个静态常量表示的状态: static...

qq_39241239的博客 7520

深入理解Java中的AQS

AQS概述 ​ AbstractQueuedSynchronizer抽象队列同步器简称AQS,它是实现同步器的基础组件,juc下面Lock的实现以及一些并发工具类就是通过AQS来实现的,这里我们通过AQS的类图先看一下大概,下面我们总结一下AQS的实现原理。先看看AQS的类图。 ​ (1)AQS是一个通过内置的FIFO双向队列来完成线程的排队工作(内部通过结点head和tail记录队首...

weixin_30472035的博客 294

从源码来理解AQS

嘻嘻

Ccc_2018 279

AQS学习笔记

AQS 学习 文章目录AQS 学习lock加锁过程acquire方法tryAcquire方法hasQueuedPredecessors方法enq方法compareAndSetTail方法addWaiter方法acquireQueued方法shouldParkAfterFailedAcquire方法parkAndCheckInterrupt方法关于加锁的流程图unlock解锁过程release方法t...

yiqzq的博客 786

耐心读懂AQS节点入队操作

(1)AQS构造的队列为双向链表,先进先出原则;只能保证先入队先获取机会,不能保证一定成功,若失败, 则继续等待; (2)入队:新节点添加到队尾,使tail指向最新入队的节点,即每次新入队的节点都会用tail标识, 保证,下一次有新节点入队时,可是通过tail直接找到,无需遍历,提高插入效率; (3)出队:设置head即可; (4)使用compareAndSetHead和compareAndSetTail保证自旋。

天然玩家的博客 1655

JUC·AQS·ReentrantLock独占模式源码解析

Aqs源码解析 从ReentrantLock入手看AQS独占模式 实例化ReentrantLock 在实例化ReentrantLock时,同时实例化了内部的非公平Aqs的类NonfairSync(默认实现为非公平同步类) lock方法 当我们想要进行同步操作时,会调用lock方法,lock方法实际调用的为Aqs中的抽象方法Lock,这里的具体实现为NonfairSync的lock方法 接下来我们来看一下,非公平的lock方法具体做了什么,如下图 当我们尝试调用NonfairSync的lock时

分享技术,记录问题,努力学习 198

java aqs源码_Java-AQS源码详解(细节很多!)

ReentrantLock调用lock()时时序图:addWaiter方法:enq方法:自旋它维护了一个volatile int state(代表共享资源)和一个FIFO线程等待队列(多线程争用资源被阻塞时会进入此队列)。这里volatile是核心关键词,具体volatile的语义,在此不述。state的访问方式有三种:getState()setState()compareAndSetState(...

weixin_35458961的博客 378
上一篇: 关于javacore和dump文件
下一篇: park/unpark 拾遗
大太阳na
大太阳na 领域专家: 后端开发技术领域 领域专家: 后端开发技术领域
博客等级 码龄9年 15万+粉丝 39原创
评论 3
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值