JUC并发包详解AQS同步队列

news2025/1/16 1:35:48

在这里插入图片描述

一、AQS介绍

在JUC并发包中,AQS为其最关键的作用,全称为abstractQueuedSynchroinzed同步器,为信号量semaphore、同步锁的基础抽象类。

在这里插入图片描述
其中内部主要有二大块

  1. state

共享资源,通过并发操作state修改改值为1,如果修改成功则表示获得锁。

  1. FIFO队列

该队列为CLH队列的变形队列,通过引入双向队列,采取自旋加堵塞的方式提高性能,其中核心为head节点、tail节点。

二、AQS队列

    /**
     * Head of the wait queue, lazily initialized.  Except for
     * initialization, it is modified only via method setHead.  Note:
     * If head exists, its waitStatus is guaranteed not to be
     * CANCELLED.
     */
    private transient volatile Node head;

    /**
     * Tail of the wait queue, lazily initialized.  Modified only via
     * method enq to add new wait node.
     */
    private transient volatile Node tail;

一个队列肯定也有队头标记、队尾标记,这里的队头标记就是Head,head是一个引用变量,会指向AQS队列的第一个节点元素,tail也是一个引用变量,也会指向AQS最后一个节点。

因为会同时多个线程节点会竞争锁,因此每一个节点都需要cas成为队尾。

2.1 head和tail的初始化

在上述注释中,明白head和tail一开始是为空的,只有多个线程竞争锁,才会进行初始化。

/**
* 当线程进行acquire失败的时候,则说明当前锁被其他线程获得,因此该线程需要进行封装成Node节点,并且插入到AQS队列中。
**/
private Node enq(final Node node) {
        for (;;) {
            Node t = tail;
            // 如果t也就是tail为空,则说明AQS队列没有值,则需要初始化head和tail
            if (t == null) { // Must initialize
                if (compareAndSetHead(new Node()))
                    tail = head;
            } else {
                node.prev = t;
                if (compareAndSetTail(t, node)) {
                    t.next = node;
                    return t;
                }
            }
        }
    }

由上面代码可知,如果aqs同步锁,一开始有一个线程获得lock,则会直接执行,当第二个过来,因为state的值为1,则需要将该线程设置为node进行入队伍,这里就会初始化对应的tail和head,可知这里的head和tail都是指向该节点。

在这里插入图片描述
当这个时候第三个线程进来,则aqs队列则会插入第三个线程c,对应tail也会发生改变。

在这里插入图片描述

 node.prev = t;
                if (compareAndSetTail(t, node)) {
                    t.next = node;
                    return t;
                }

2.2 waitstatus状态值

waitStatus有如下几种状态:

  1. CANCELLED(1):当前节点取消获取锁。当等待超时或被中断(响应中断),会触发变更为此状态,进入该状态后节点状态不再变化;
  2. SIGNAL(-1):后面节点等待当前节点唤醒;
  3. CONDITION(-2):Condition 中使用,当前线程阻塞在 Condition,如果其他线程调用了 Condition 的 signal 方法,这个结点将从等待队列转移到同步队列队尾,等待获取同步锁;
  4. PROPAGATE(-3):共享模式,前置节点唤醒后面节点后,唤醒操作无条件传播下去;
  5. 0:中间状态,当前节点后面的节点已经唤醒,但是当前节点线程还没有执行完成。

但是对于AQS的同步锁的队列需要去除CONDITION状态,在这里我们先不考虑PROPAGATE状态;

2.2.1 CANCELLED

waitstatus > 0 的时候只有一种状态为CANCElED也就是当前节点为取消状态,如果当前节点被等待超时了或者被中断了,则会变成该状态。

  1. 赋值时机

ReentrantLock提供tryLock(int time,TimeUnit), lockInterrupt()方法,也就是说获得锁的时候会去设置超时时间,或者设置可中断,在节点等待过程中如果发送了超时、中断则会将该节点的waitstatus设置为1,并且返回lock方法为false,表示未获得锁。
在这里插入图片描述当线程被取消时,它对应的节点会被标记为取消状态,并从同步队列中清除

2.2.2 waitstatus初始状态0

我们发现这里有一个状态为0, 0表示为节点未加入队列的状态,也就是初始状态。

  1. 如果该节点为tail节点,则该状态一直为0,如果该节点有后续节点,后续节点在park之前会将pre节点设置为-1也就是SIGNAL, 但是如果该节点为第一个节点,则还是会被设置为-1,因为它自己的pre节点就是本身。具体参考shouldParkAfterFailedAcquire。

在这里插入图片描述

2.2.3 SIGNAL状态

我们在2.2.2可知道,如果节点进行park会将前节点的值设置为signal,那么这里的signal有什么用呢?

signal的状态表示:后面节点等待当前节点唤醒;
在这里插入图片描述
在release的时候会去唤醒后续节点。
在这里插入图片描述

三、如何基于AQS实现一个可重入锁

AQS提供了如下自定义方法

  1. tryAcquire
  2. tryRelease
  3. tryAcquireShared
  4. tryReleaseShared
  5. isHeldExclusively : 判断是否为独占锁

在编写一个锁的话,如果是独占锁,则需要实现tryAcquire和tryRelease和isHeldExclusively。

其中编写需要实现的就是对state进行操作,也就是state是为共享变量,如果state==0则表示该aqs锁未被占用,如果state>0,则表示该aqs被锁占用。

如果要使用一个锁对象,类似ReentrantLock(可重入锁),则需要实现Lock接口,该接口提供如下方法:
在这里插入图片描述
则需要在锁对象中创建继承aqs的内部类,并且实现对应的tryAcqurie方法、tryRelase方法以及isHeldExclusively方法。

tryAcqurie:获得锁
tryRelease: 释放锁
isHeldExclusively: 判断当前线程是否拥有锁

在这里插入图片描述
在这里插入图片描述

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

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

相关文章

《Linux 内核设计与实现》09. 内核同步介绍

共享资源之所以要防止并发访问,是因为如果多个执行线程同时访问和操作数据,就有可能发生各线程之间相互覆盖共享数据的情况,从而造成被访问的数据不一致状态。 临界区和竞争条件 临界区:访问和操作共享数据的代码段。原子操作&a…

键控流水灯

项目文件 文件 关于项目的内容知识点可以见专栏单片机原理及应用 的第四章 IO口编写 在电路图的基础上,编写可键控的流水灯程序。要求实现的功能为,K1是总开关,当K1首次按下时,流水灯由下往上流动;当K2按下时停止流动,且全部灯灭…

ASK,FSK和PSK

一、ASK,FSK和PSK 数字信号只有有限个离散值,使用数字信号对载波进行调制的方式称为键控(Keying),分为幅度键控(ASK)、频移键控(FSK)和相移键控(PSK)。 幅度键控可以通过乘法器和开关电路来实现,在数字信…

SpringBoot【开发实用篇】---- 配置高级

SpringBoot【开发实用篇】---- 配置高级 1. ConfigurationProperties2. 宽松绑定/松散绑定3. 常用计量单位绑定4. 校验5. 数据类型转换 进入开发实用篇第二章内容,配置高级,其实配置在基础篇讲了一部分,在运维实用篇讲了一部分,这…

离线安装Percona

前言 安装还是比较简单,这边简单进行记录一下。 版本差异 一、离线安装Percona 下载percona官网 去下载你需要对应的版本 jemalloc-3.6.0-1.el7.x86_64.rpm 需要单独下载 安装Percona 进入RPM安装文件目录,执行下面的脚本 yum localinstall *.rpm修改…

C语言CRC-16 X25格式校验函数

C语言CRC-16 X25格式校验函数 CRC-16校验产生2个字节长度的数据校验码,通过计算得到的校验码和获得的校验码比较,用于验证获得的数据的正确性。基本的CRC-16校验算法实现,参考: C语言标准CRC-16校验函数。 不同应用规范通过对输…

聊聊Doris向量化执行引擎-过滤操作

聊聊Doris向量化执行引擎-过滤操作 Doris是开源的新一代极速MPP数据库,和StarRocks同源,采用全面向量化技术,充分利用CPU单核资源,将单核执行性能做到极致。本文,我们聊聊过滤操作是如何利用SIMD指令进行向量化操作。 …

PCB设计流程步骤中的注意事项

PCB中文名称为印制电路板,又称印刷线路板,几乎所有电子设备中都会应用到PCB。这种由贵金属制成的绿色电路板连接了设备的所有电气组件,并使其能够正常运行。PCB原理图是一个计划,是一个蓝图。它说明的并不是组件将专门放置在何处&…

【51单片机HC6800-EM3 V3.0】动态数码管显示,原理分析,连线操作

🎊专栏【51单片机】 🍔喜欢的诗句:更喜岷山千里雪 三军过后尽开颜。 🎆音乐分享【如愿】 大一同学小吉,欢迎并且感谢大家指出我的问题🥰 目录 🍔提醒 🎊连线图片 🎊原理…

基于SSM框架扶贫信息综合平台前台管理系统(spring+springmvc+mybatis+jsp+jquery+css)

一、项目简介 本项目是一套基于SSM框架扶贫信息综合平台前台管理系统,主要针对计算机相关专业的正在做毕设的学生与需要项目实战练习的Java学习者。 包含:项目源码、数据库脚本等,该项目附带全部源码可作为毕设使用。 项目都经过严格调试&am…

【刷题】138. 复制带随机指针的链表

138. 复制带随机指针的链表 一、题目描述二、示例三、实现 138. 复制带随机指针的链表 一、题目描述 给你一个长度为 n 的链表,每个节点包含一个额外增加的随机指针 random ,该指针可以指向链表中的任何节点或空节点。 构造这个链表的 深拷贝。 深拷贝…

Matlab论文插图绘制模板第90期—带权重的有向图/图论图/网络图

在之前的文章中,分享了Matlab有向图的绘制模板: 进一步,如果我们想标注有向图的每条边的权重,或者直接用线条的粗细来表示权重,该怎么操作呢? 先来看一下成品效果: 特别提示:本期内…

洛谷P5047 [Ynoi2019 模拟赛] Yuno loves sqrt technology II(离线区间逆序对+莫队二次离线)

题目 给你一个长为n(1<n<1e5)的序列a(0<ai<1e9)&#xff0c; m(1<m<1e5)次询问&#xff0c;每次查询一个区间[l,r]的逆序对数&#xff0c;可离线。 思路来源 登录 - 洛谷 三道经典分块题的更优复杂度解法&[Ynoi2019模拟赛]题解 - 博客 - OldDriverT…

(异或相消)猫猫数字异或和

E - Red Scarf (atcoder.jp) 刚入坑写的一道题被我拉出来对比分析了 我的思路&#xff1a; 垃圾运气选手凭借直觉乱搞猜出来的&#xff0c;没有思路。 题解思路&#xff1a; 由问题陈述中XOR的定义&#xff0c;我们可以看出计算3个或更多整数的XOR可以以任意顺序进行&#…

fastjson 代码执行 (CNVD-2017-02833)

漏洞存在原因 在fastjson<1.2.24版本中&#xff0c;在解析json的过程中&#xff0c;支持使用autoType来实例化某一个具体的类&#xff0c;并调用该类的set/get方法来访问属性。而在1.24<fastjson<1.2.48版本中后增加了反序列化白名单。 漏洞复现过程如下 在vulfocu…

解读ChatGPT中的RLHF

无论是 ChatGPT 还是 GPT-4&#xff0c;它们的核心技术机制之一都是基于人类反馈的强化学习&#xff08;Reinforcement Learning from Human Feedback&#xff0c;RLHF&#xff09;。这是大型语言模型生成领域的新训练范式&#xff0c;即以强化学习方式依据人类反馈优化语言模型…

打造属于自己的私人云笔记

打造属于自己的私人云笔记 前言效果环境标题第一步 网盘部署开启webDAV协议使用 前言 现在市面上支持私有化部署的云笔记选择不多&#xff0c;而且大多数只支持mackDown语法&#xff0c;不支持word等其他文件的编辑&#xff0c;基于此需求&#xff0c;能不能有一款笔记软件&am…

盛元广通高等级生物安全实验室(P3)管理系统

近年来&#xff0c;传染性疾病频发&#xff0c;给传染病防控和生物安全带来了前所未有的挑战&#xff0c;重点构建集生物安全三级实验室&#xff0c;统一布局科技研究和科技力量&#xff0c;成为重要传染病原和生物防范基础及应用基础研究的高地&#xff0c;高等级生物安全实验…

JavaScript实现输入长方形的宽和高,输出周长和面积的代码

以下为实现输入长方形的宽和高&#xff0c;输出周长和面积的代码和运行截图 目录 前言 一、实现输入长方形的宽和高&#xff0c;输出周长和面积 1.1 运行流程及思想 1.2 代码段 1.3 JavaScript语句代码 1.4 输入数值不是要求必须输入数值的代码 1.5 运行截图 前言 1.若…

这款视频录制剪辑软件千万别错过!

案例&#xff1a;有没有录制完成之后&#xff0c;可以直接剪辑视频的软件&#xff1f; 【我的工作经常需要对电脑上的内容进行录制、剪辑。我每次都需要使用录屏工具录制完成后&#xff0c;再使用视频剪辑工具进行剪辑&#xff0c;十分麻烦。想问一下有没有软件既能录屏又能剪…