【退役之重学 Java】初步认识 AQS

一、AQS 是什么

  • Abstract Queued Synchronizer ,翻译过来就是“抽象的排好队的同步器”。 AQS 是一个用来构建锁和同步器的框架。
  • 是用来构建锁或者其他同步器组件的重量级基础框架及整个JUC体系的基石,通过内置的FIFO队列来完成线程获取资源的排队工作,并通过一个int类型变量表示持有锁的状态。

二、AQS 有什么用

  • 使用 AQS 能简单高效的构造出大量被广泛应用的同步器,比如 ReentrantLock,Semaphore,ReentrantReadWriteLock,SynchronousQueue,FutureTask等等,都是基于 AQS 的。
  • 我们也可以使用 AQS 轻松构造出符合特定需求的同步器。
  • 加锁会导致阻塞,有阻塞就需要排队,实现排队必然需要有某种形式的队列(CLH)来进行管理

三、AQS 的核心思想

  • 如果被请求的共享资源空闲,则将当前请求资源的线程设置为有效的工作线程,
  • 并且将共享资源设置为锁定状态。
  • 如果被请求的共享资源被占用,那么就需要一套线程阻塞等待以及被唤醒时锁分配的机制
  • 这个机制是 AQS 使用 CLH队列锁实现的,即将暂时获取不到锁的线程加入到队列中。
  • CLH 是一个虚拟的双向FIFO队列,AQS 将每个请求共享资源的线程封装成Node 节点,并放入CLH
  • AQS 使用一个volatile 的 int 类型的变量来表示同步状态,通过内置的FIFO队列来完成资源获取的排队工作将每条要去抢占资源的线程封装成一个Node节点来实现锁的分配,通过CAS完成对State值的修改

四、AQS 基本结构

在这里插入图片描述

五、AQS 怎么用

  • 创建任一基于AQS实现的同步器
  • 创建多个线程,并分别使用同步器的 lock 和 unlock 方法
  • 会发现,这些线程是一个一个执行的,而非一起执行的,说明锁成功了。

六、进一步理解锁和同步器的关系

  • 锁,面相锁的使用者,定义了程序员和锁交互的使用层API
  • 同步器,面相锁的实现者,

七、源码分析

  1. Lock --> Syn -----> AQS,所以Lock 最终继承的是AQS
  2. lock(),acquire(),tryAcquire(arg),addWaiter(Node.EXCLUSIVE),addQueued(addWaiter(Node.EXCLUSIVE),arg)
    在这里插入图片描述
  3. head和tail
    • 是什么?
      head 和 tail 分别是头指针和尾指针,分别指向队列中的头节点和尾节点
    • 有什么用?
      方便出队和入队操作,也方便逻辑判断(暂时是这么理解的)
  4. 哨兵节点有什么用?
    队列中的哨兵节点在并发编程中起到了重要的作用。哨兵节点是一种特殊的节点,通常用于帮助管理和控制并发队列的行为。在使用队列实现同步器时,哨兵节点可以用来简化逻辑提高效率确保线程安全
  5. 确实有点复杂,但我感觉不应该去理解源码的每一行代码,而应该从整体设计思想去理解就好了,以后有机会自己实现一个简陋的example。
  6. 出队操作:第一个真实节点B抢占资源成功,哨兵节点出队,B变成新的哨兵节点

参考博客 一文让你彻底搞懂AQS(通俗易懂的AQS)
声明:仅用于学习,不做其他用途。本文对所引用的博客,进行了摘抄、整理,其中AQS 的知识点并不详尽,希望未来有机会能够更加深入地讲解它。


扩展

一、可重入锁

  • 可重入锁,又名递归锁。是指在同一个线程,在外层方法获取锁的时候,再进入线程的内层方法时,会自动获取锁(前提,锁对象得是同一个对象),不会因为之前已经获取过还没释放而阻塞
  • Java 中 ReentrantLock 和 Synchronized 都是可重入锁
  • 可重入锁的一个优点是可以一定程度避免死锁
  • 一句话概括:同一个线程可以多次获得属于自己的同一把锁,一定程度避免死锁

二、 LockSupport

  1. 是什么
    LockSupport 用于创建锁和其他同步类的基本线程阻塞原语。
  2. 有什么用
    • 对于原有锁支持线程等待唤醒机制(wait/nofify)的加强、改良版
    • LockSupport 的 park()和 unpark()的作用分别是阻塞线程和解除阻塞线程
    • 两个三角形:
      • (synchronized,wait,notify)
      • (lock,await,signal)
  3. 核心思想
    • LockSupport 使用了一种名为 Permit (许可)的概念来做到阻塞和唤醒线程的功能,每个线程都有一个许可(permit),permit 只有两个值1和0,默认为零
    • 可以把许可看成一种(0,1)信号量(Semaphore),但是与Semaphore 不同的是,许可的累加上限是1
  4. 怎么用
    • LockSupport.park() 阻塞
    • LockSupport.unpark(a) 唤醒啊
    • 什么叫阻塞,什么叫唤醒?
    • 阻塞就是说,在那一步线程就转换为“等待执行”的状态
    • 唤醒就是说,让线程继续执行
    • unpark()可以在park()之前执行
  5. 优点
    LockSupport 是一个线程阻塞工具类,所有的方法都是静态方法,可以让线程在任意位置阻塞,阻塞之后也有对应的唤醒方法。归根结底,LockSupport 调用 Unsafe 中的native 代码。
  6. 为什么可以先唤醒线程后阻塞线程?
    因为unpark 获得了一个凭证,之后,在调用 park 方法,就可以名正言顺的凭证消费,故不会阻塞。

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

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

相关文章

251 基于matlab的动态粒子群算法

基于matlab的动态粒子群算法。普通粒子群算法无法感知外界环境的变化,在外界环境发生改变时无法实时进行响应,因而缺乏动态环境寻优能力。在普通粒子群算法基本上通过增加敏感粒子得到一种动态粒子群算法,该算法通过实时计算敏感粒子的适应度…

2024年第七届可再生能源与电力工程国际会议(REPE 2024)即将召开!

2024年第七届可再生能源与电力工程国际会议(REPE 2024)将于2024年9月25-27日在中国北京召开, 由清华大学主办。REPE 2024将汇聚国内外知名专家学者通过主旨报告、分组讨论和互动交流等形式,分享最新的研究成果、技术进展和应用案例&#xff0…

【教程向】从零开始创建浏览器插件(二)深入理解 Chrome 扩展的 manifest.json 配置文件

第二步:深入理解 Chrome 扩展的 manifest.json 配置文件 上一次我们已经着手完成了一个自己的浏览器插件,链接在这里:我是链接 在本篇博客中,我们将更详细地探讨 Chrome 扩展中的 manifest.json 文件。这个文件是每个浏览器扩展…

docker容器实现https访问

前言: 【云原生】docker容器实现https访问_docker ssl访问-CSDN博客 一术语介绍 ①key 私钥 明文--自己生成(genrsa ) ②csr 公钥 由私钥生成 ③crt 证书 公钥 签名(自签名或者由CA签名) ④证书&#xf…

C入门笔记

1. c文件执行过程 C语言程序的执行过程可以分为四个基本步骤:预处理、编译、汇编和链接。下面是这些步骤的简要概述: 预处理:在这个步骤中,预处理器将源代码中以 # 开头的指令进行处理,例如 #include 和 #define。预…

STM32快速入门(定时器之输出PWM波形)

STM32快速入门(定时器之输出PWM波形) 前言 本节主要讲解STM32利用通用定时器,利用CCR和CNT寄存器,输出指定占空比和频率的PWM波形。其功能的应用有:实现LED呼吸灯的效果、控制步进电机、控制直流电机转速等。 导航 …

ue5地编模块学习记录

ue5网站功能3d溜溜网下载模型https://anyconv.com/max-to-fbx-converter/3dmax转换fbx模型解决问题记录 一、光源 搜索光源搜索不到的时候可以点击 窗口> 对场景内的光照进行处理

最佳解决Maven同一依赖多版本共存问题,重复依赖(同一个jar包,多个版本)-maven-shade-plugin

先看链接:原文链接 参照原文链接生成的文件(下面是我放的位置) mvn指令 mvn install:install-file -DfileD:\mavenrepository/maven-shade.jar -DgroupIdcom.wj -DartifactIdmaven-shade -Dversion1.1 -Dpackagingjar如果配置了maven_home 和java_home可以任意打开cmd执行(…

Google: 在新知识上微调大语言模型是否会鼓励产生幻觉?

摘要 当大型语言模型通过监督式微调进行对齐时,它们可能会遇到在预训练期间没有获得的新事实信息。人们经常推测,这可能会教导模型产生事实上不正确的回应的行为,因为模型被训练成生成没有基于其预先存在的知识的事实。在这项工作中,Google研究了这种暴露在新知识下对微调后模…

基于springboot实现高校教师电子名片系统项目【项目源码+论文说明】计算机毕业设计

基于springboot实现高校教师电子名片系统演示 摘要 传统信息的管理大部分依赖于管理人员的手工登记与管理,然而,随着近些年信息技术的迅猛发展,让许多比较老套的信息管理模式进行了更新迭代,名片信息因为其管理内容繁杂&#xff…

C++的数据结构(五):树和存储结构及示例

在计算机科学中,树是一种抽象数据类型(ADT)或是实现这种抽象数据类型的数据结构,用来模拟具有树状结构性质的数据集合。这种数据结构以一系列连接的节点来形成树形结构。在C中,树的概念和存储结构是实现各种复杂算法和…

Java--初识类和对象

前言 本篇讲解Java类和对象的入门版本。 学习目的: 1.理解什么是类和对象。 2.引入面向对象程序设计的概念 3.学会如何定义类和创建对象。 4.理解this引用。 5.了解构造方法的概念并学会使用 考虑到篇幅过长问题,作者决定分多次发布。 面向对象的引入 J…

GIAT: 蛋白质结构预测的新利器

瑞典Karolinska研究院在瑞典政府赞助下由Ben Murrell等研究团队在AlphaFold 3最新报告后提出这篇论文提出了一种非常有趣和创新的方法来生成蛋白质骨架结构,称为生成式不变角度转换器(GIAT)。与现有的主要基于扩散模型和流匹配的方法不同,GIAT采用了类似于大型语言模型(如GPT)中…

【C语言|数据结构】双向链表

文章目录 前言1、初步认识双向链表1.1 定义:1.2 结构1.3 节点的存储 2、双向链表的接口函数2.1 链表的节点的动态申请2.2 链表的初始化2.3 尾插2.4 头插2.5 头删2.5 尾删2.6 在pos节点后面添加数据2.6 删除pos节点 3、双向链表的实现: 前言 各位小伙伴大…

C控制语句:分支和跳转

1.1if语句 //colddays.c --找出0摄氏度以下的天数占总天数的百分比 #include <stdio.h>int main(void) {const int FREEZING 0;float temperature;int cold_days 0;int all_days 0;printf("Enter the list of daily low temperature.\n");printf("Use…

电子学会C/C++编程等级考试2024年03月(八级)真题解析

C/C编程&#xff08;1~8级&#xff09;全部真题・点这里 第1题&#xff1a;道路 N个以 1 … N 标号的城市通过单向的道路相连:。每条道路包含两个参数&#xff1a;道路的长度和需要为该路付的通行费&#xff08;以金币的数目来表示&#xff09; Bob and Alice 过去住在城市 1.在…

蓝海创业商机小吃配方项目,日入200+ ,小白可上手,图文创作转现快

小吃技术销售&#xff0c;一单价格从几元到几百元不等&#xff0c;行业竞争相对较小&#xff0c;是一个相对冷门的领域。只需一部手机&#xff0c;就可以发布图文并茂的内容&#xff0c;配上背景音乐&#xff08;BGM&#xff09;&#xff0c;即使是对视频剪辑不熟悉的新手&…

面试中算法(金矿)

有一位国王拥有5座金矿&#xff0c;每座金矿的黄金储量不同&#xff0c;需要参与挖掘的工人人数也不同。 例如&#xff0c;有的金矿储量是5ookg黄金&#xff0c;需要5个工人来挖掘;有的金矿储量是2ookg黄金&#xff0c;需要3个工人来挖掘...... 如果参与挖矿的工人的总数是10。…

试衣不再有界:Tunnel Try-on开启视频试衣应用新纪元

论文&#xff1a;https://arxiv.org/pdf/2404.17571 主页&#xff1a;https://mengtingchen.github.io/tunnel-try-on-page/ 一、摘要总结 随着虚拟试衣技术的发展&#xff0c;消费者和时尚行业对于能够在视频中实现高质量虚拟试衣的需求日益增长。这项技术允许用户在不实际穿…

目标检测——印度车辆数据集

引言 亲爱的读者们&#xff0c;您是否在寻找某个特定的数据集&#xff0c;用于研究或项目实践&#xff1f;欢迎您在评论区留言&#xff0c;或者通过公众号私信告诉我&#xff0c;您想要的数据集的类型主题。小编会竭尽全力为您寻找&#xff0c;并在找到后第一时间与您分享。 …