秋招突击——8/19——知识补全——AQS深入

news/2024/9/20 2:28:36/ 标签: AQS, 同步框架, 抽象同步队列

文章目录

    • 引言
    • 正文
      • AQS介绍
      • AQS核心原理
        • 不同锁的获取方式
      • Condition原理
        • await方法
        • signal方法
    • 八股
      • 1、获取同步状态的节点,何时移出队列
      • 2、公平锁和非公平锁体现在什么地方
    • 总结

引言

  • 之前看过AQS,仅仅是知道他是什么,然后知道哪些方法,怎么用的,但是没有阅读过源码,或者说看过具体的数据结构,在面试字节的时候,被拷打了,虽然蒙对了, 但是写的很糙,这里来加深一下对应的理解,系统地学习一下!

  • 第一次粗浅学习的链接

正文

AQS_8">AQS介绍

AQS抽象队列同步器

  • 构建锁和其他同步组件的基础框架

主要构成

  • 使用volatile修饰的int成员变量state
    • 读写锁会使用高低位来记录读写的状态
  • 内置的FIFO队列完成获取资源线程的排队工作

典型应用

  • 可重入锁ReentrantLock
  • 读写锁ReentrantReadWriteLock
  • CountDownLatch
  • Semephere

在这里插入图片描述

AQS_27">AQS核心原理

1、队列基本结构

  • 同步器包含两个节点的引用(头节点和尾节点)

在这里插入图片描述

2、队列节点

  • 节点Node是构成同步队列的基础,获取同步状态失败的线程将被会包装成一个节点加入同步队列的尾部
  • 主要信息构成如下
    • waitStatus:1表示取消,-1表示等待通知后继节点,-2表示在阻塞队列中等等
    • prev:同步队列种的前驱节点
    • next:同步队列中的后继节点
    • nextWaiter:等待队列中的后继节点
    • thread:获取同步状态的线程

3、新加入节点的过程

  • 公平锁
    • 竞争锁之前,首先判定同步队列是否存在头节点
      • 不存在头节点,尝试获取锁
      • 存在头节点,加入同步队列的尾部
  • 非公平锁
    • 直接参与竞争锁,CompareAndSetState
      • 如果尝试竞争锁失败,加入尾节点
      • 如果竞争锁成功,访问对应的锁
        注意
  • 最后加入尾节点的时候需要通过CAS判断,防止多个线程竞争
    在这里插入图片描述

4、释放节点的过程

  • 首节点是获取同步状态成功的节点
    • 首节点对应的线程在释放同步状态时,唤醒后继节点
    • 后继节点在获取同步状态成功是,将自己设置为首节点
      在这里插入图片描述
不同锁的获取方式

共享式获取和独占式获取

  • 获取锁失败
    • 线程会被加入到队列中,并在队列中自旋
      • 自旋:在源码中是判断前驱节点是否为头节点
  • 释放同步状态时
    • 同步器调用tryRelease方法,释放同步状态,唤醒头节点和后继节点

在这里插入图片描述

Condition原理

  • 是和锁配合实现等待和通知模式的辅助类
    实现
  • Condition是AQS的内部类==》Condition的操作需要获取相关联的锁
  • 每一个Condition对象都有一个等待队列
    • 通过等待队列实现等待通知功能
      在这里插入图片描述
await方法

基本流程

  • 1、使当前线程释放锁,当前线程是同步队列中的首节点
  • 2、然后进入等待队列,同时线程状态变为waiting等待状态

从队列的角度看,就是同步队列中的首节点移动到了等待队列中

在这里插入图片描述

signal方法

基本流程

  • 唤醒等待队列中的首节点(等待时间最长的节点),
  • 等待队列中的节点移动到同步队列中,开始加入到获取同步状态的竞争中
    在这里插入图片描述

注意

  • 唤醒的线程会从await方法开始执行

一般在八股中的多线程编程练习中,都是使用reentrantlock,同步队列只有一个节点,然后其余所有线程都在同步队列,借此来实现对线程执行的控制

八股

1、获取同步状态的节点,何时移出队列

  • 同步状态被后继节点获取之后

2、公平锁和非公平锁体现在什么地方

  • 非公平锁在加入同步队列之前,不管队列有没有节点,会进行一次tryAcquire,然后再加入队列
  • 公平锁,会先判定队列是不是空的,然后在决定要不要竞争锁。

总结

  • 大概了解了一下,没时间看源码了,本来是想看源码的,但是这周又有面试,得花时间准备一下对应的面经!
  • 下次再问我AQS,我就很了解了,不用再害怕了!

http://www.ppmy.cn/news/1511513.html

相关文章

Go更换国内源配置环境变量

背景 要在中国境内下载和使用Go编程语言的包,可以使用国内的Go模块代理来加速下载速度。以下是一些常见的国内Go模块代理源以及如何切换到这些源的方法: 常见国内Go模块代理源 七牛云(Qiniu) https://goproxy.cn 阿里云&#xff0…

SVG中的paint-order属性实现文字描边

过去只支持 SVG 元素 paint-order&#xff0c;表示绘制的顺序。 对于一个图形的绘制&#xff0c;顺序还是非常重要的。例如用SVG来绘制一个带边框的矩形 <style>rect{fill: #FFE8A3;stroke: #9747FF;stroke-width: 4;} </style><svg viewBox"0 0 300 30…

【RH134知识点问答题】第7章 管理基本存储

目录 1. 对 Linux 磁盘进行分区时有哪两种方案&#xff1f;分别加以详细说明。 2. 简单说下创建 MBR 磁盘分区涉及哪几个步骤&#xff1f; 3. 创建 GPT 分区与创建 MBR 分区有什么不同&#xff1f; 4. 在创建分区时就会在分区上创建文件系统吗&#xff1f; 5. 如何持久挂载…

mac电脑安装Zsh并启用

安装 Zsh 1. 安装 Zsh 新版mac系统会默认安装并使用zsh&#xff0c;如没用&#xff0c;需在终端中安装&#xff1a; brew install zsh2. 安装 Oh My Zsh 克隆Oh My Zsh到你的目录&#xff1a; git clone https://github.com/robbyrussell/oh-my-zsh.git ~/.oh-my-zsh3. 复…

SpringBoot整合定时任务@Scheduled

SpringBoot自带的定时任务非常简单操作&#xff0c;其实就是一个Scheduled注解。 第一步&#xff1a;创建类&#xff0c;定义执行定时任务的方法 package com.oracle.springboottimer.timer;import org.springframework.scheduling.annotation.Scheduled; import org.springfr…

探索Go语言中的列表与环形缓冲区:container/list与container/ring全解析

标题&#xff1a;探索Go语言中的列表与环形缓冲区&#xff1a;container/list与container/ring全解析 在Go语言的丰富标准库中&#xff0c;container/list和container/ring提供了列表和环形缓冲区的实现&#xff0c;这些数据结构对于处理序列数据和实现高效的生产者-消费者队列…

所生成项目的处理器架构“MSIL”与引用“***”的处理器架构“x86”不匹配。

在c#工程里新建了一个类库&#xff0c;编译的场合出现以下警告&#xff1a;C:\Program Files\Microsoft Visual Studio\2022\Enterprise\MSBuild\Current\Bin\amd64\Microsoft.Common.CurrentVersion.targets(2401,5): warning MSB3270: 所生成项目的处理器架构“MSIL”与引用“…

Qt五大核心特性之对象模型

前言 在开始之前我查阅对象模型的资料的时候发现一搜标题是对象模型&#xff0c;但是内容是对象树&#xff0c;这俩又不是一个东西&#xff0c;而且还不是一个人这么写。 正文 对象模型&#xff08;Object Model&#xff09; 对象模型是指 Qt 中 QObject 提供的一种基本编程…

Python爬虫入门教程(非常详细)适合零基础小白

一、什么是爬虫&#xff1f; 1.简单介绍爬虫 爬虫的全称为网络爬虫&#xff0c;简称爬虫&#xff0c;别名有网络机器人&#xff0c;网络蜘蛛等等。 网络爬虫是一种自动获取网页内容的程序&#xff0c;为搜索引擎提供了重要的数据支撑。搜索引擎通过网络爬虫技术&#xff0c;将…

在 Go 语言中,字符串格式化拼接可以通过多种方法实现

在 Go 语言中&#xff0c;字符串格式化拼接可以通过多种方法实现。以下是几种常见的方法&#xff1a; 1. 使用 fmt.Sprintf 使用 fmt 包的 Sprintf 函数格式化字符串。 package mainimport ("fmt" )func main() {name : "Alice"age : 30str : fmt.Sprin…

Unity | 游戏开发中的优化思维

目录 ​​​​​​一、优化三板斧&#xff1a; 第1步&#xff1a;定标准 第2步&#xff1a;重数据 第3步&#xff1a;严测试 二、流程和性能的优化 1.定标准&#xff1a; 2.重数据&#xff1a; 三、交互和表现的优化 1.卡顿和延迟 2.手感硬 四、沟通和学习 ​​​​…

水库大坝安全预警系统的作用

“汛情就是命令&#xff0c;防汛就是责任”&#xff0c;为了防治和减轻洪涝带来的危害&#xff0c;需要一种以预警为先导的临灾位移监测系统--水库大坝安全预警系统&#xff0c;对可能会出现的灾害进行实时远程监控&#xff0c;尽可能做到隐患早发现、早决策、早治理&#xff0…

出国留学如何兼顾学习与生活?

留学无疑首先是一种人生经历&#xff0c;这种经历是一直待在国内没法体验。留学不仅仅是学知识&#xff0c;也是了解、融入西方社会的一条重要通道。学习之外的东西&#xff0c;对于留学生个人形成完整的人生观、世界观以及价值观是非常重要的。呼吸清新的空气&#xff0c;体会…

深度学习基础—正则化

正则化&#xff1a;解决模型过拟合的手段&#xff0c;本质就是减小模型参数取值&#xff0c;从而使模型更简单。常用范数如下&#xff1a; 使用最多的是L2范数正则项&#xff0c;因此加入正则项的损失函数变为&#xff1a; 使用梯度下降法的权重调整公式&#xff1a; 推导后得到…

yolov5-6.1训练过程中的问题总结

目录 1. torch安装问题2. ‘FreeTypeFont‘ object has no attribute ‘getsize‘报错解决3. RuntimeError: result type Float cant be cast to the desired output type __int644. AttributeError: module numpy has no attribute int5. failed: module ‘signal‘ has no at…

ThinkPHP中Db事务的使用:删除操作的示例

开启事务 在进行删除操作前&#xff0c;我们需要先开启一个事务&#xff0c;以便我们可以对操作进行回滚&#xff08;撤销&#xff09;如果出现错误。我们可以使用以下代码来开启一个新的事务&#xff1a; Db::startTrans();执行删除操作 接下来&#xff0c;我们将执行删除操作…

c# 什么是扩展方法

官方解释 扩展方法使你能够向现有类型“添加”方法&#xff0c;而无需创建新的派生类型、重新编译或以其他方式修改原始类型。 扩展方法是一种静态方法&#xff0c;但可以像扩展类型上的实例方法一样进行调用。 对于用 C#、F# 和 Visual Basic 编写的客户端代码&#x…

uniapp left right 的左右模态框

标题 这是组件 <template><div class"content-wrapper"><divv-for"(vla, i) in products":key"i":class"[content-page, getPageClass(i)]"><slot :data"vla"><!-- 用户自定义的内容 --><…

【前端面试】挖掘做过的nextJS项目(下)——详谈服务端渲染

nextjs做服务端渲染是基于nodejs&#xff0c;node环境与浏览器环境有很大区别——模块系统、web api Next.js 怎么支持SSR&#xff0c;同时又使用 Web API Next.js 支持服务器渲染&#xff08;Server-Side Rendering, SSR&#xff09;的代码使用 Web API&#xff0c;主要是通…

Spire.PDF for .NET【文档操作】演示:检测 PDF 文件是否为 PDF/A

Spire.PDF 为开发人员提供了两种方法来检测 PDF 文件是否为 PDF/A。一种是使用 PdfDocument.Conformance 属性&#xff0c;另一种是使用 PdfDocument.XmpMetaData 属性。以下示例演示了如何使用这两种方法检测 PDF 文件是否为 PDF/A。 Spire.PDF for .NET 是一款独立 PDF 控件…