当前位置: 首页 > news >正文

深入理解AQS

  1. 概念

设计初衷:该类利用 状态+队列 实现了一个同步器,更多的是提供一些模板方法(子类必须重写,不然会抛错)。
设计功能:独占、共享模式
  1. 两个核心,state、Queue

2.1 state

setState、compareAndSetState都是用于修改同步状态。看类名其实就知道一个是线程不安全的(setState),一个是使用了乐观锁来保证线程安全(compareAndSetState)。

  • 使用场景

  • setState:应用于释放资源的线程,因为同一时间只有一个使用这个线程不安全的方法去修改state的值,所以不会发生并发安全问题

  • compareAndSetState:应用于尝试获取同步器的资源,由于同一时间可能存在多个资源竞争锁,所以需要使用unsfte类的cas保证线程安全

private volatile int state; // 同步状态值,0:空闲,>0:有多少个线程在同步队列中等待
protected final int getState() { // 获取同步状态return state;
}
protected final void setState(int newState) { // 修改同步状态state = newState;
}
protected final boolean compareAndSetState(int expect, int update) {return unsafe.compareAndSwapInt(this, stateOffset, expect, update); // 通过unsafe类的cas修改同步状态
}

2.2 Queue

底层:带头、尾节点的双向链表
private transient volatile Node head; // 头节点
private transient volatile Node tail; // 尾节点
static final class Node {volatile Node prev; // 前一个节点volatile Node next; // 后一个节点
}
  1. 核心获取同步锁流程

3.1 acquire

public final void acquire(int arg) {// 尝试获取资源失败,且成功加入同步队列,则阻塞线程if (!tryAcquire(arg) &&acquireQueued(addWaiter(Node.EXCLUSIVE), arg)) selfInterrupt(); // 获取不到资源或者加入队列失败,那就中断该线程
}

3.2 tryAcquire

protected boolean tryAcquire(int arg) {throw new UnsupportedOperationException(); // 模板方法,让子类实现
}

3.3 addWaiter

private Node addWaiter(Node mode) {Node node = new Node(Thread.currentThread(), mode); // 转化为同步节点(队列节点类型)// 尾插法Node pred = tail; // 指向尾节点if (pred != null) {node.prev = pred; // 新节点的前一个节点指向尾节点if (compareAndSetTail(pred, node)) { // 因为同时间内有多个线程进入队列,所以使用cas置换尾节点pred.next = node; // 原尾节点的下一个指针指向新插入的节点return node;}}enq(node); // 队列为空,需要初始化队列插入return node;
}

3.4 enq

private Node enq(final Node node) {for (;;) { // 自旋,创建到成功为止Node t = tail;if (t == null) { // 还是并发安全问题,保守判断一下,是不是有人抢先一步if (compareAndSetHead(new Node()))tail = head;} else {node.prev = t; // 插入节点指向尾巴if (compareAndSetTail(t, node)) { // 交换尾节点t.next = node; // 上一个节点指向当前插入节点return t; }}}
}

3.5 acquireQueued

final boolean acquireQueued(final Node node, int arg) {boolean failed = true;try {boolean interrupted = false;for (;;) {final Node p = node.predecessor(); // 获取上一个节点if (p == head && tryAcquire(arg)) { // 检查一下上一个节点是不是头节点,是的话尝试获取资源setHead(node); // 设置头节点为当前节点p.next = null; // GC掉,因为当前节点获取到资源,说明上一个节点已经执行完毕业务了failed = false; // 设置成功return interrupted; // 不阻塞}if (shouldParkAfterFailedAcquire(p, node) && // 没有获取到资源,把线程挂起,别浪费资源parkAndCheckInterrupt())interrupted = true;}} finally {if (failed)cancelAcquire(node); // 获取到资源,取消尝试获取资源}
}

3.6 shouldParkAfterFailedAcquire

private static boolean shouldParkAfterFailedAcquire(Node pred, Node node) {int ws = pred.waitStatus; // 上一个节点的wait状态if (ws == Node.SIGNAL) // 上一个节点是SIGNAL状态,说明可以阻塞,回去等通知就行return true;if (ws > 0) { // 如果大于0,说明是CANCELLED状态,那就把前面那些废物节点扔掉do {node.prev = pred = pred.prev;  } while (pred.waitStatus > 0); // 扔啊扔,扔到前一个节点不是废物节点pred.next = node;} else {compareAndSetWaitStatus(pred, ws, Node.SIGNAL); // 小于0,说明前面有节点,更改成SIGNAL状态}return false;
}

3.6.1 waitStatus

static final int CANCELLED =  1; // 废弃状态,有些加入了又不想等,就玩儿
static final int SIGNAL    = -1; // 等待激活下一个节点的状态,下一个节点肯定是被Condiction.await()
static final int CONDITION = -2; // 条件状态,中间节点
static final int PROPAGATE = -3; // 共享模式下的节点状态

3.7 parkAndCheckInterrupt

private final boolean parkAndCheckInterrupt() {LockSupport.park(this); // 挂起当前线程return Thread.interrupted();
}

3.7.1 interrupted

public static boolean interrupted() {return currentThread().isInterrupted(true); // 获取当前线程是否为中断状态
}
private native boolean isInterrupted(boolean ClearInterrupted); // 清除中断标志
  1. 获取同步锁流程图

相关文章:

深入理解AQS

概念设计初衷:该类利用 状态队列 实现了一个同步器,更多的是提供一些模板方法(子类必须重写,不然会抛错)。 设计功能:独占、共享模式两个核心,state、Queue2.1 statesetState、compareAndSetSta…...

JVM学习笔记十:执行引擎

0. 前言 声明: 感谢尚硅谷宋红康老师的讲授。 感谢广大网友共享的笔记内容。 B站:https://www.bilibili.com/video/BV1PJ411n7xZ 本文的内容基本来源于宋老师的课件,其中有一些其他同学共享的内容,也有一些自己的理解内容。 1. …...

【2023-03-10】JS逆向之美团滑块

提示:文章仅供参考,禁止用于非法途径 前言 目标网站:aHR0cHM6Ly9wYXNzcG9ydC5tZWl0dWFuLmNvbS9hY2NvdW50L3VuaXRpdmVsb2dpbg 页面分析 接口流程 1.https://passport.meituan.com/account/unitivelogin主页接口:需获取下面的参数&#xff0…...

全志V853芯片放开快启方案打印及在快起方式下配置isp led的方法

全志V85x芯片 如何放开快启方案的打印? 1.主题 如何放开快启方案的打印 2.问题背景 产品:v851系列快启方案 软件:tina 其他:特有版本信息添加自由描述 (如固件版本,复现概率,特定环境&#x…...

大数据 | (一)Hadoop伪分布式安装

大数据原理与应用教材链接:大数据技术原理与应用电子课件-林子雨编著 Hadoop伪分布式安装借鉴文章:Hadoop伪分布式安装-比课本详细 大数据 | (二)SSH连接报错Permission denied:SSH连接报错Permission denied 哈喽&a…...

Django/Vue实现在线考试系统-06-开发环境搭建-Django安装

1.0 基本介绍 Django 是一个由 Python 编写的一个开放源代码的 Web 应用框架。 使用 Django,只要很少的代码,Python 的程序开发人员就可以轻松地完成一个正式网站所需要的大部分内容,并进一步开发出全功能的 Web 服务 Django 本身基于 MVC 模型,即 Model(模型)+ View(…...

KaiwuDB 时序引擎数据存储内存对齐技术解读

一、理论1、什么是内存对齐现代计算机中内存空间都是按照 byte 划分的,在计算机中访问一个变量需要访问它的内存地址,从理论上看,似乎对任何类型的变量的访问都可以从任何地址开始。但在实际情况中,通常在特定的内存地址才能访问特…...

IR 808 Alkyne,IR-808 alkyne,IR 808炔烃,近红外吲哚类花菁染料

【产品理化指标】:中文名:IR-808炔烃英文名:IR-808 alkyne,Alkyne 808-IR CAS号:N/AIR-808结构式:规格包装:10mg,25mg,50mg,接受各种复杂PEGS定制服务&#x…...

elasticsearch

这里写目录标题1.初识ElasticSearch1.1 了解ES1.2 倒排索引1.2.1 正向索引1.2.2 倒排索引1.2.3 正向和倒排1.3 ES的一些概念1.3.1 文档和字段1.3.2 索引和映射1.3.3 mysql和elasticsearch1.4 安装ES、kibana1.初识ElasticSearch 1.1 了解ES elasticsearch是一款非常强大的开源…...

并发编程---java锁

java锁一 多线程锁synchronized案例分析1.1synchronized介绍1.2 synchronized案例分析1.2.1.标准访问,请问先打印邮件还是短信?1.2.2.邮件⽅法暂停4秒钟,请问先打印邮件还是短信?分析1.2.3.新增⼀个普通⽅法hello(&…...

品牌营销 | 学习如何最大限度地发挥品牌营销的作用

您是否想过如何最大限度地发挥品牌营销的潜力?这是一项艰巨的挑战,通过了解品牌营销的基本组成部分,您可以成功地推广您的品牌。 (图源:Pixabay) 品牌营销的基本组成部分 你需要做什么来发展稳固的品牌&am…...

Linux驱动的同步阻塞和同步非阻塞

在字符设备驱动中,若要求应用与驱动同步,则在驱动程序中可以根据情况实现为阻塞或非阻塞一、同步阻塞这种操作会阻塞应用程序直到设备完成read/write操作或者返回一个错误码。在应用程序阻塞这段时间,程序所代表的进程并不消耗CPU的时间&…...

LearnOpenGL-光照-5.投光物

本人刚学OpenGL不久且自学,文中定有代码、术语等错误,欢迎指正 我写的项目地址:https://github.com/liujianjie/LearnOpenGLProject 文章目录投光物平行光点光源聚光不平滑的例子平滑例子投光物 前面几节使用的光照都来自于空间中的一个点 即…...

【C语言】每日刷题 —— 牛客语法篇(1)

前言 大家好,今天带来一篇新的专栏c_牛客,不出意外的话每天更新十道题,难度也是从易到难,自己复习的同时也希望能帮助到大家,题目答案会根据我所学到的知识提供最优解。 🏡个人主页:悲伤的猪大…...

【深度学习】Subword Tokenization算法

在自然语言处理中,面临的首要问题是如何让模型认识我们的文本信息,词,是自然语言处理中基本单位,神经网络模型的训练和预测都需要借助词表来对句子进行表示。 1.构建词表的传统方法 在字词模型问世之前,做自然语言处理…...

五分钟了解支付、交易、清算、银行等专业名词的含义?

五分钟了解支付、交易、清算、银行等专业名词的含义?1. 支付类名词01 支付应用02 支付场景03 交易类型04 支付类型(按通道类型)05 支付类型(按业务双方类型)06 支付方式07 支付产品08 收银台类型09 支付通道10 通道类型…...

4个工具,让 ChatGPT 如虎添翼!

LightGBM中文文档 机器学习统计学,476页 机器学习圣经PRML中文版...

初识PO、VO、DAO、BO、DTO、POJO时

PO、VO、DAO、BO、DTO、POJO 区别分层领域模型规约DO(Data Object)DTO(Data Transfer Object)BO(Business Object)AO(ApplicationObject)VO(View Object)Query领域模型命名规约:一、PO :(persistant object ),持久对象二、VO :(value object) &#xff0…...

[2.2.4]进程管理——FCFS、SJF、HRRN调度算法

文章目录第二章 进程管理FCFS、SJF、HRRN调度算法(一)先来先服务(FCFS, First Come First Serve)(二)短作业优先(SJF, Shortest Job First)对FCFS和SJF两种算法的思考(三…...

【代码随想录Day55】动态规划

583 两个字符串的删除操作 https://leetcode.cn/problems/delete-operation-for-two-strings/72 编辑距离https://leetcode.cn/problems/edit-distance/...

终极指南:用WarcraftHelper彻底解决魔兽争霸III现代系统兼容性问题

终极指南:用WarcraftHelper彻底解决魔兽争霸III现代系统兼容性问题 【免费下载链接】WarcraftHelper Warcraft III Helper , support 1.20e, 1.24e, 1.26a, 1.27a, 1.27b 项目地址: https://gitcode.com/gh_mirrors/wa/WarcraftHelper 还在为魔兽争霸III在Wi…...

Python Redis 缓存策略实战:提升应用性能的最佳实践

Python Redis 缓存策略实战:提升应用性能的最佳实践 引言 在后端开发中,缓存是提升系统性能的关键技术。作为一名从Rust转向Python的开发者,我深刻认识到缓存策略在高并发场景下的重要性。Redis作为一款高性能的内存数据库,已成为…...

手把手教你用C语言实现三相锁相环(附完整源码与仿真波形分析)

手把手教你用C语言实现三相锁相环(附完整源码与仿真波形分析) 在电力电子和电机控制领域,锁相环(PLL)技术是实现电网同步、逆变器控制的核心组件。传统教材往往停留在理论推导,而实际工程中,如何…...

系统提示、开发提示、用户提示:在 Agent 里怎么分层

系统提示、开发提示、用户提示在 Agent 里的分层架构:从理论到工业级落地全解析 副标题:基于认知科学、软件工程双视角,构建可复用、可调试、高智能的三层提示架构体系 第一部分:引言与基础 (Introduction & Foundation) 1.1 引人注目的标题(重复+锚定SEO) 系统提…...

避坑指南:LabVIEW做3D模型旋转动画时,90%的人会忽略的‘添加对象及引用’模式

LabVIEW 3D模型旋转动画深度解析:从"乱跑"到精准控制的进阶指南 在LabVIEW中创建3D模型旋转动画时,许多开发者都会遇到一个令人困惑的现象:明明只想让模型旋转,结果整个坐标系也跟着"翩翩起舞"。这种看似简单…...

技术债务的职场政治:谁该为历史遗留问题买单

在软件测试从业者的日常工作中,技术债务是一个绕不开的话题。它像一颗隐藏在代码深处的定时炸弹,随时可能在项目推进的某个节点爆发,引发一系列连锁反应。而当技术债务问题浮出水面时,一场关于“谁该为历史遗留问题买单”的职场政…...

DES算法C++实现踩坑实录:S盒置换与比特操作的那些坑

DES算法C实现中的五大典型陷阱与解决方案 在实现DES算法的过程中,许多开发者都会遇到一些看似简单却容易导致加密结果错误的细节问题。本文将聚焦于实际编码中最常见的五个"坑点",通过具体案例分析和解决方案,帮助开发者快速定位和…...

工业物联网长距离蓝牙环境监测方案解析

1. 项目概述在工业物联网和远程环境监测领域,如何实现低功耗、长距离的数据传输一直是个技术难点。传统蓝牙技术受限于通信距离(通常10米以内),而Wi-Fi方案又面临功耗过高的问题。最近我在一个工厂环境监测项目中,成功…...

告别Wireshark手动分析:用Python的flowcontainer库5分钟搞定pcap流量特征提取

用Python的flowcontainer库实现pcap流量特征自动化提取 每次面对几十GB的pcap文件时,你是否也厌倦了在Wireshark中反复点击、筛选、导出数据的繁琐操作?网络流量分析是安全研究和数据挖掘的基础工作,但传统的手动分析方法效率低下&#xff0…...

AI建站多语言怎么做?先懂业务,再谈翻译

AI建站多语言怎么做?先懂业务,再谈翻译当同行还在卷“建站速度”时,聪明的出海商家已经开始卷“AI可见度”了。据近期行业数据显示,超过60%的海外采购商开始习惯使用ChatGPT、Perplexity等AI工具寻找供应商,而非传统的…...