锁(二)队列同步器AQS

一、队列同步器AQS

1、定义

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

2、实现

同步器的设计是基于模板方法模式的,也就是说,使用者需要继承同步器并重写指定的方法,随后将同步器组合在自定义同步组件的实现中,并调用同步器提供的模板方法。

主要使用方式是继承。在实现抽象方法时,避免不了修改同步器的状态。需要用到同步器的三个方法(getState(),setState(int newState)和compareAndSetState(int expect,int update))。推荐子类被定义为自定义同步组件的静态内部类。

同步器提供的模板方法基本上分为3类:独占式获取与释放同步状态、共享式获取与释放、同步状态和查询同步队列中的等待线程情况。

3、队列同步器

AbstractQueuedSynchronized 抽象队列式的同步器,AQS定义了一套多线程访问共享资源的同步器框架,许多同步类实现都依赖于它,如常用的ReentrantLock/Semaphore/CountDownLatch…

  

  AQS维护了一个volatile int state(代表共享资源)和一个FIFO线程等待队列(多线程争用资源被阻塞时会进入此队列)。

  state的访问方式有三种: getState() 、setState() 、compareAndSetState()

  AQS定义两种资源共享方式:Exclusive(独占,只有一个线程能执行,如ReentrantLock)和Share(共享,多个线程可同时执行,如Semaphore/CountDownLatch)。

  不同的自定义同步器争用共享资源的方式也不同。自定义同步器在实现时只需要实现共享资源state的获取与释放方式即可,至于具体线程等待队列的维护(如获取资源失败入队/唤醒出队等),AQS已经在顶层实现好了。自定义同步器实现时主要实现以下几种方法:

 isHeldExclusively():该线程是否正在独占资源。只有用到condition才需要去实现它。tryAquire(int):独占方式。尝试获取资源,成功则返回true,失败则返回false。tryRelease(int):独占方式。尝试释放资源,成功则返回true,失败则返回false。tryAcquireShared(int):共享方式。尝试获取资源。负数表示失败;0表示成功,但没有剩余可用资源;正数表示成功,且有剩余资源。tryReleaseShared(int):共享方式。尝试释放资源,如果释放后允许唤醒后续等待结点返回true,否则返回false。

  以ReentrantLock为例,state初始化为0,表示未锁定状态。A线程lock()时,会调用tryAcquire()独占该锁并将state+1。此后,其他线程再tryAcquire()时就会失败,直到A线程unlock()到state=0(即释放锁)为止,其他线程才有机会获取该锁。当然,释放锁之前,A线程自己是可以重复获取此锁的(state会累加),这就是可重入的概念。但要注意,获取多少次就要释放多少次,这样才能保证state是能回到零态的。

  再以CountDownLatch为例,任务分为N个子线程去执行,state为初始化为N(注意N要与线程个数一致)。这N个子线程是并行执行的,每个子线程执行完后countDown()一次,state会CAS减1。等到所有子线程都执行完后(即state=0),会unpark()主调用线程,然后主调用线程就会await()函数返回,继续后余动作。

  一般来说,自定义同步器要么是独占方法,要么是共享方式,他们也只需实现tryAcquire-tryRelease、tryAcquireShared-tryReleaseShared中的一种即可。但AQS也支持自定义同步器同时实现独占和共享两种方式,如ReentrantReadWriteLock。

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

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

相关文章

如何安装x11vnc并结合cpolar实现win远程桌面Deepin

文章目录 1. 安装x11vnc2. 本地远程连接测试3. Deepin安装Cpolar4. 配置公网远程地址5. 公网远程连接Deepin桌面6. 固定连接公网地址7. 固定公网地址连接测试 正文开始前给大家推荐个网站,前些天发现了一个巨牛的 人工智能学习网站, 通俗易懂&#xff…

11.0 Zookeeper watcher 事件机制原理剖析

zookeeper 的 watcher 机制,可以分为四个过程: 客户端注册 watcher。服务端处理 watcher。服务端触发 watcher 事件。客户端回调 watcher。 其中客户端注册 watcher 有三种方式,调用客户端 API 可以分别通过 getData、exists、getChildren …

GLSL ES 1.0

GLSL ES 概述 写在前面 程序是大小写敏感的每一个语句都应该以英文分号结束一个shader必须包含一个main函数,该函数不接受任何参数,并且返回voidvoid main() { }数据值类型 GLSL支持三种数据类型: 整型浮点型:必须包含小数点&…

python 动态显示数据。

界面显示动态的数据。 from time import sleep import serialimport tkinter as tklis[1,10,40] # 打开串行端口 ser serial.Serial(COM3, 9600) # 9600为波特率,根据实际情况进行调整# 创建窗口和画布 window tk.Tk() canvas tk.Canvas(window, width400, heig…

高阶滤波器

一阶后向差分:s(1-z^(-1))/T dx/dt[x(k)-x(k-1)]/T[x(k)-x(k)z^(-1)]/Tx(k)*(1-z^(-1))/T 一阶前向差分:s(z-1)/T dx/dt[x(k1)-x(k)]/T[z*x(k)-x(k)]/Tx(k)*(z-1)/T 双线性差分:s(2/T)*(1-z…

通过 docker-compose 部署 Flink

概要 通过 docker-compose 以 Session Mode 部署 flink 前置依赖 Docker、docker-composeflink 客户端docker-compose.yml version: "2.2" services:jobmanager:image: flink:1.17.2ports:- "8081:8081"command: jobmanagervolumes:- ${PWD}/checkpoin…

【大模型上下文长度扩展】FlashAttention:高效注意力计算的新纪元

FlashAttention:高效注意力计算的新纪元 核心思想核心操作融合,减少高内存读写成本分块计算(Tiling),避免存储一次性整个矩阵块稀疏注意力,处理长序列时的效率问题利用快速 SRAM,处理内存与计算…

【大模型上下文长度扩展】LongQLoRA:单GPU(V100)环境下的语言模型优化方案

LongQLoRA 核心问题子问题1: 预定义的上下文长度限制子问题2: 训练资源的需求高子问题3: 保持模型性能分析不足 LongQLoRA方法拆解子问题1: 上下文长度限制子问题2: 高GPU内存需求子问题3: 精确量化导致的性能损失分析不足效果 论文:https://arxiv.org/pdf/2311.048…

docker镜像结构

# 基础镜像 FROM openjdk:11.0-jre-buster # 设定时区 ENV TZAsia/Shanghai RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone # 拷贝jar包 COPY docker-demo.jar /app.jar # 入口 ENTRYPOINT ["java", "-jar"…

游泳耳机推荐性价比排行榜,四大高性价比游泳耳机推荐

随着运动健康意识的提高,越来越多的朋友选择在游泳馆进行锻炼。然而,在水中享受音乐并非易事,这就需要一款真正防水的耳机。尽管市面上有许多声称具备防水功能的耳机产品,但实际使用中往往难以达到理想的防水效果。为了帮助大家找…

之前看过的前序遍历的线索二叉树感觉写的有点问题 这里更新一下我的思路

前序线索化 #include<iostream> using namespace std;typedef int datatype; typedef struct BitNode {datatype Data;struct BitNode* leftchild;struct BitNode* rightchild;int lefttag;int righttag; }Node; #pragma region 前序线索化递归遍历 Node* previous NUL…

maven依赖报错处理(或者maven怎么刷新都下载不了依赖)

maven依赖报错&#xff0c;或者不报错&#xff0c;但是怎么刷新maven都没反应&#xff0c;可以试一下以下操作 当下载jar的时候&#xff0c;如果断网&#xff0c;或者连接超时的时候&#xff0c;会自动在文件夹中创建一个名为*lastupdate的文件&#xff0c;当有了这个文件之后…

网络工程师专属春节对联,不要太真实了!

中午好&#xff0c;我的网工朋友。 都放假了没&#xff1f;龙年将至&#xff0c;都有啥新年计划&#xff1f; 过年&#xff0c;讲究的就是一个热闹&#xff0c;可以暂时告别辛苦的一年&#xff0c;重新整装出发。 热闹可少不了春联啊&#xff0c;红红火火又一年&#xff0c;…

Vue源码系列讲解——虚拟DOM篇【一】(Vue中的虚拟DOM)

目录 1. 前言 2. 虚拟DOM简介 2.1什么是虚拟DOM&#xff1f; 2.2为什么要有虚拟DOM&#xff1f; 3. Vue中的虚拟DOM 3.1 VNode类 3.2 VNode的类型 3.2.1 注释节点 3.2.2 文本节点 3.2.3 克隆节点 3.2.4 元素节点 3.2.5 组件节点 3.2.6 函数式组件节点 3.2.7 小结 3…

OpenCV-31 获得形态学卷积核

OpenCV提供了获取卷积核的API&#xff0c;不需要我们手动创建卷积核。 通过下面API---getStructuringElement(shape&#xff0c;ksize&#xff0c;[, anchor]) shape是指卷积核的型状&#xff0c;注意不是指长宽&#xff0c;是指卷积核中1形成的形状。MORPH_RECT 卷积核中的1…

(三)elasticsearch 源码之启动流程分析

https://www.cnblogs.com/darcy-yuan/p/17007635.html 1.前面我们在《&#xff08;一&#xff09;elasticsearch 编译和启动》和 《&#xff08;二&#xff09;elasticsearch 源码目录 》简单了解下es&#xff08;elasticsearch&#xff0c;下同&#xff09;&#xff0c;现在我…

SPSS基础操作:对数据进行加权处理

对数据进行加权处理是我们使用SPSS提供某些分析方法的重要前提。对数据进行加权后&#xff0c;当前的权重将被保存在数据中。当进行相应的分析时&#xff0c;用户无须再次进行加权操作。本节以对广告的效果观测为例&#xff0c;讲解数据的加权操作。本例给出了消费者购买行为与…

Arthas使用教程—— 阿里开源线上监控诊断产品

文章目录 1 简介2背景3 图形界面工具 arthas 阿里开源3.1 &#xff1a;启动 arthas3.2 help :查看arthas所有命令3.3 查看 dashboard3.4 thread 列出当前进程所有线程占用CPU和内存情况3.5 jvm 查看该进程的各项参数 &#xff08;类比 jinfo&#xff09;3.6 通过 jad 来反编译 …

端口扫描神器:御剑 保姆级教程(附链接)

一、介绍 御剑&#xff08;YooScan&#xff09;是一款网络安全工具&#xff0c;主要用于进行端口扫描。它具有直观的用户界面&#xff0c;方便用户进行端口扫描和信息收集。以下是御剑端口扫描工具的一些主要特点和功能&#xff1a; 图形用户界面&#xff1a; 御剑提供直观的图…

告别mPDF迎来TCPDF和中文打印遇到的问题

mPDF是一个用PHP编写的开源PDF生成库。它最初由Claus Holler创建&#xff0c;于2004年发布。原来用开源软件打印中文没有问题&#xff0c;最近发现新的软件包中mPDF被TCPDF代替了&#xff0c;当然如果只用西文的PDF是没有发现问题&#xff0c;但要打印中文就有点抓瞎了如图1&am…