JAVA并发之谈谈你对AQS的理解

news2025/7/12 22:29:21

文章目录

  • 一、AQS是什么
  • 二、AQS具备哪些特性
  • 三、用的哪种设计模式
  • 四、AQS与锁二者之间的关系
  • 五、如何基于AQS实现一把独占锁
  • 六、参考资料

一、AQS是什么

AQS的全称是 (AbstractQueuedSynchronizer ),它定义了一套多线程访问共享资源的同步器框架,是 J.U.C 包中多个组件的底层实现,如 Lock、CountDownLatch、Semaphore 等都用到了 AQS。

通过查看AbstractQueuedSynchronizer的实现类如下图:
aqs

二、AQS具备哪些特性

  1. 阻塞等待队列
    1.1 获取锁失败的线程会进入到一个阻塞等待队列中。
  2. 共享 / 独占
    从本质上来说,AQS 提供了两种锁机制,分别是独占锁,和共享锁。
    2.1 独占锁,就是存在多线程竞争同一共享资源时,同一时刻只允许一个线程访问该共享资源,也就是多个线程中只能有一个线程获得锁资源,比如 Lock 中的ReentrantLock 重入锁实现就是用到了 AQS 中的排它锁功能。
    2.2 共享锁也称为读锁,就是在同一时刻允许多个线程同时获得锁资源,比如CountDownLatch 和 Semaphore 都是用到了 AQS 中的共享锁功能。
  3. 公平/非公平
    3.1 公平:线程在获取锁失败时,直接进入阻塞队列。
    3.2 非公平:线程在获取锁失败时,进入阻塞队列总会再尝试一次获取锁,插队
  4. 可重入
    4.1 对于同一把锁,获取锁的当前线程可以重复获取。
  5. 允许中断
    5.1 提供中断机制,来干预线程之间的通信或协作。

三、用的哪种设计模式

     模板方法模式

四、AQS与锁二者之间的关系

  1. 锁是面向使用者的,它定义了使用者与锁交互的接口,隐藏了实现细节。
  2. 同步器是面向锁的实现者,它简化了锁的实现方式,屏蔽了同步状态管理、线程的排队、等待与唤醒等底层操作。
  3. 锁和同步器很好地隔离了使用者和实现者所需关注的领域。

看两张图吧:

以独占锁ReentrantLock为例:

ReentrantLock

ReentrantLock实现了Lock的接口,没有直接与AQS交互,而是通过一个内部Sync类继承AQS,将同步器的所有调用都映射到对应的Sync对应的方法。

ReentrantLock加锁方法 lock():

lock

查看 Sync的类图继承关系如下:

在这里插入图片描述

五、如何基于AQS实现一把独占锁

  1. 因为AQS内部帮我们把像多线程访问共享资源获取锁失败时,线程 入队、出队、阻塞、唤醒 提供好了,所以实现一把锁非常容易。
  2. 我们只需要关注加锁方法 tryAcquire 和释放锁资源方法 tryRelease 即可,其他的AQS已经为我们实现好了。

代码如下:

/**
 * Created with IntelliJ IDEA.
 * @Author: zhaoxn
 * @Date: 2022/11/25/21:51
 * @Description:基于AQS实现一把互斥锁
 */
public class MutexLock extends AbstractQueuedSynchronizer{

    @Override
    protected boolean tryAcquire(int unused) {
        //cas 加锁
        if (compareAndSetState(0, 1)) {
            setExclusiveOwnerThread(Thread.currentThread());
            return true;
        }
        return false;
    }

    @Override
    protected boolean tryRelease(int unused) {
        //释放锁
        setExclusiveOwnerThread(null);
        setState(0);
        return true;
    }

    //调用AQS内部的tryAcquire方法获取锁,失败需要入队或成功直接返回
    public void lock() {
        acquire(1);
    }

    //调用自己重写的tryAcquire方法获取锁,失败或成功直接返回
    public boolean tryLock() {
        return tryAcquire(1);
    }

    //重写释放锁资源的方法,至于释放锁以后唤醒队列中阻塞的线程,交给AQS内部就好了
    public void unlock() {
        release(1);
    }
    

}

六、参考资料

         Java并发编程的艺术

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

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

相关文章

【算法基础】(一)基础算法 --- 归并排序

✨个人主页:bit me ✨当前专栏:算法基础 🔥专栏简介:该专栏主要更新一些基础算法题,有参加蓝桥杯等算法题竞赛或者正在刷题的铁汁们可以关注一下🌹 🌹 🌹 归并排序💤一.归…

猴子也能学会的jQuery第十期——jQuery元素操作(上)

📚系列文章—目录🔥 猴子也能学会的jQuery第一期——什么是jQuery 猴子也能学会的jQuery第二期——引用jQuery 猴子也能学会的jQuery第三期——使用jQuery 猴子也能学会的jQuery第四期——jQuery选择器大全 猴子也能学会的jQuery第五期——jQuery样式操作…

基于拟蒙特卡洛模拟法的随机潮流计算matlab程序

电力系统随机潮流计算中常采用模拟法,该方法原理简单、使用方便,能够精确地模拟实际物理过程,但是简单的蒙特卡洛模拟法收敛速度很慢,要得到精确的结果需要以大量的计算时间为代价。本章在此基础上提出了基于拟蒙特卡洛模拟的随机…

【菜菜的sklearn课堂笔记】逻辑回归与评分卡-用逻辑回归制作评分卡-异常值和样本不均衡处理

视频作者:菜菜TsaiTsai 链接:【技术干货】菜菜的机器学习sklearn【全85集】Python进阶_哔哩哔哩_bilibili 描述性统计处理异常值 现实数据永远都会有一些异常值,首先我们要去把他们捕捉出来,然后观察他们的性质。注意&#xff0c…

【雷达检测】基于复杂环境下的雷达目标检测技术附Matlab代码

✅作者简介:热爱科研的Matlab仿真开发者,修心和技术同步精进,matlab项目合作可私信。 🍎个人主页:Matlab科研工作室 🍊个人信条:格物致知。 更多Matlab仿真内容点击👇 智能优化算法 …

3.6、媒体接入控制

1、基本概念 有多台主机连接到这根同轴电缆上,共享这跟传输媒体,形成了总线型的局域网。 各主机竞争使用总线,随机的在信道发送数据。 主机 C 与主机 D 同时使用总线来发送数据,这必然会产生所发送信号的碰撞 2、静态划分信道…

二阶锥松弛在配电网最优潮流计算中的应用(IEEE33节点配电网最优潮流算例matlab程序)(yalmip+cplex)

二阶锥规划在配电网最优潮流计算中的应用IEEE33节点配电网最优潮流算例matlab程序(yalmipcplex) 参考文献:二阶锥规划在配电网最优潮流计算中的应用 最优潮流计算是电网规划、优化运行的重要基础。首先建立了配电网全天有功损耗最小化的最优…

ABAP学习笔记之——第四章:模块化程序

一、子程序: 语法: 参数: 参数(Parameter)是指调用子程序时用于传入、传出的值。子程序中的参数与一般用 DATA语句定义的局部变量相同。调用子程序时使用的参数叫实参(Actual Parameter),在子程序中使用的参数叫虚参(Formal Par…

nginx(六十八)http_proxy模块 nginx与上游的ssl握手

一 nginx作为客户端与上游的SSL/TLS握手 理解上: nginx作为客户端,此时类似浏览器的角色,发请求建立连接 nginx作为server端与下游进行SSL/TLS握手 ① nginx与后端选择什么样的协议 1)如果nginx与上游是局域网内,一般通过http建立请求,不需要进行…

使用flv.js + websokect播放rtsp格式视频流

1.问题背景 在最近的项目中,涉及到海康接入的视频播放的问题,海康这边获取到的视频流是rtsp格式,web端目前没有直接可以播放的组件,于是最开始是后端处理了视频流,返回hls格式的m3u8地址,这样用videojs插件…

进程【JavaEE初阶】

目录 一、操作系统 二、进程 2.1 进程的概念 2.2 进程的管理 2.3 PCB 2.3.1 PCB里面的一些属性 2.3.2 进程的调度 2.3.3 进程的虚拟地址空间 2.3.4 进程间通信 一、操作系统 CPU、存储器、输入设备、输出设备,这些实物看得着摸得到的,都属于 …

web前端-javascript-switch条件分支语句(语法,执行流程,补充)

文章目录条件分支语句(switch 语句)1. 语法;2. 执行流程:2.1. 在执行时会依次将 case 后的条件表达式的值和 switch 后的条件表达式的值进行全等比较2.2. 如果比较结果为 true,则从当前 case 处开始执行代码2.3. 如果比较结果为 false&#x…

【知识网络分析】研究机构合作网络(co-investigator institution)

研究机构合作网络(co-investigator institution) 1 网络数据集读取2 网络最大子群数据获取与精简3 中心点指定网络半径子群获取4 节点中心度相关指标计算1 网络数据集读取 使用GC.networkCoInvestigatorInstitution()方法快速生成研究结构合作网络数据集,其中GC代表着读入p…

解析华为OSPF协议

文章目录 前言一、pandas是 目录 文章目录 OSPF基础 一、报文类型 二、LSA类型 三.LSA在各区域中传播的支持情况 四.邻居状态机 邻居关系 邻接关系 8种状态机: OSPF报文认证 OSPF缺省路由 2.读入数据 总结 什么?二、使用步骤 1.引入库2.读入数…

卷积神经网络CNN各层基本知识

卷积神经网络 卷积神经网络(CNN)由输入层、卷积层、激活函数、池化层以及全连接层构成。 INPUT(输入层)-CONV(卷积层)-RELU(激活函数)-POOL(池化层)-FC(全连接层&#…

[VNCTF2022]easyj4va

看源码 输入 /file?url 1报错 用伪协议可以读取到内容 /file?urlfile:///etc/passwd 然后就是查看java字节码文件的目录 file?urlfile:///usr/local/tomcat/webapps/ROOT/WEB-INF 这里官方给了另外一个协议netdoc,跟file用法是一样的,但是这个netd…

JDK动态代理与Cglib动态代理使用详解

JDK动态代理与Cglib动态代理使用详解一、JDK动态代理准备使用二、Cglib动态代理准备使用Enhancer.create(Class type, Callback callback)Enhancer.create((Class superclass, Class[] interfaces, Callback callback))Enhancer.create(Class superclass, Class[] interfaces, …

【学习笔记35】JavaScript计算两个指定日期的时间差

一、要求 计算两个指定日期的时间差(2023年元旦到来的时间) 二、分析 先获取到两个时间距离1970(格林尼时间)~~~毫秒数计算两个毫秒数的差值 ----> 得到了总毫秒数计算总毫秒数内, 有多少个完整的天 parseInt(总毫秒数 / 一天的…

会话跟踪技术-session和cookie

会话(Session)跟踪是Web程序中常用的技术,用来跟踪用户的整个会话。常用的会话跟踪技术是Cookie与Session。 Cookie通过在客户端记录信息确定用户身份,Session通过在服务器端记录信息确定用户身份。 Cookie对象与HttpSession对象简…

nginx(六十七)http_ssl模块 client与nginx的ssl握手

一 HTTPS握手机制 关注点: SSL/TLS握手的细节与nginx配置指令的关系核心: 讲解客户端(下游)与作为server端的nginx之间的握手最佳实践: 建议在http块中通过include ssl.conf把共工部分抽离处理ssl/tls报错原因:可能是客户端或服…