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

java并发之AQS

一、简介

AQS,全称:AbstractQueuedSynchronizer,是一个JDK提供的用于构建锁、同步器等线程协作工具类的框架,内部维护FIFO双向队列(双向链表实现)。
AQS重要属性:

// 表示同步状态。它既可以表示独占模式下的锁状态,也可以表示共享模式下的资源数量。通过修改state字段,可以实现多线程的独占或共享模式‌
private volatile int state
// 当前持有独占锁的线程
private transient Thread exclusiveOwnerThread
// 头节点
private transient volatile Node head;
// 尾节点
private transient volatile Node tail;

Node节点重要属性:

// 加入队列的线程
volatile Thread thread;
// 前驱节点
volatile Node prev;
// 后继节点
volatile Node next;
// CANCELLED: 表示线程已经取消了对同步状态的请求。
// SIGNAL: 表示线程需要被唤醒(通常是因为其他线程释放了同步状态)。
// CONDITION: 表示线程正在等待某个条件。
// PROPAGATE: 表示下一次共享状态的释放应该传播到其他线程。
// 0: 初始状态,表示节点没有特定的状态。
volatile int waitStatus;
Node nextWaiter;

AQS 在 ReentrantLock、ReentrantReadWriteLock、Semaphore、CountDownLatch、ThreadPoolExcutor 的 Worker 中都有运用(JDK 1.8),AQS 是这些类的底层原理。

二、实现自定义线程协作工具类

2.1 实现独占锁

重写AQS以下方法

boolean tryAcquire(int arg)
boolean tryRelease(int arg)
boolean isHeldExclusively()

调用AQS以下方法

public final void acquire(int arg) {if (!tryAcquire(arg) &&acquireQueued(addWaiter(Node.EXCLUSIVE), arg))selfInterrupt();
}public final boolean release(int arg) {if (tryRelease(arg)) {Node h = head;if (h != null && h.waitStatus != 0)unparkSuccessor(h);return true;}return false;
}
2.2 实现共享锁

重写AQS以下方法

int tryAcquireShared(int arg)
boolean tryReleaseShared(int arg)

调用AQS以下方法

public final void acquireShared(int arg) {if (tryAcquireShared(arg) < 0)doAcquireShared(arg);
}public final boolean releaseShared(int arg) {if (tryReleaseShared(arg)) {doReleaseShared();return true;}return false;
}public final void acquireSharedInterruptibly(int arg)throws InterruptedException {if (Thread.interrupted())throw new InterruptedException();if (tryAcquireShared(arg) < 0)doAcquireSharedInterruptibly(arg);
}
2.3 示例
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.AbstractQueuedSynchronizer;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;public class Test {class MySync extends AbstractQueuedSynchronizer {@Overrideprotected boolean tryAcquire(int arg) {if (compareAndSetState(0, 1)) {setExclusiveOwnerThread(Thread.currentThread());return true;}return false;}@Overrideprotected boolean tryRelease(int arg) {setExclusiveOwnerThread(null);setState(0);return true;}@Overrideprotected boolean isHeldExclusively() {return getState() == 1;}public Condition newCondition() {return new ConditionObject();}}class MyLock implements Lock {private MySync sync = new MySync();@Overridepublic void lock() {sync.acquire(1);}@Overridepublic void lockInterruptibly() throws InterruptedException {sync.acquireInterruptibly(1);}@Overridepublic boolean tryLock() {return sync.tryAcquire(1);}@Overridepublic boolean tryLock(long time, TimeUnit unit) throws InterruptedException {return sync.tryAcquireNanos(1, unit.toNanos(time));}@Overridepublic void unlock() {sync.release(1);}@Overridepublic Condition newCondition() {return sync.newCondition();}}public static void main(String[] args) throws Exception {Test test = new Test();MyLock myLock = test.new MyLock();Thread t1 = new Thread(new Runnable() {@Overridepublic void run() {try {myLock.lock();System.out.println(Thread.currentThread().getName() + "执行开始");Thread.sleep(5000L);System.out.println(Thread.currentThread().getName() + "执行结束");} catch (InterruptedException e) {e.printStackTrace();} finally {myLock.unlock();}}}, "t1");Thread t2 = new Thread(new Runnable() {@Overridepublic void run() {try {myLock.lock();System.out.println(Thread.currentThread().getName() + "执行开始");Thread.sleep(3000L);System.out.println(Thread.currentThread().getName() + "执行结束");} catch (InterruptedException e) {e.printStackTrace();} finally {myLock.unlock();}}}, "t2");Thread t3 = new Thread(new Runnable() {@Overridepublic void run() {try {myLock.lock();System.out.println(Thread.currentThread().getName() + "执行开始");Thread.sleep(1000L);System.out.println(Thread.currentThread().getName() + "执行结束");} catch (InterruptedException e) {e.printStackTrace();} finally {myLock.unlock();}}}, "t3");t1.start();t2.start();t3.start();}
}
  • 参考1

相关文章:

java并发之AQS

一、简介 AQS&#xff0c;全称&#xff1a;AbstractQueuedSynchronizer&#xff0c;是一个JDK提供的用于构建锁、同步器等线程协作工具类的框架&#xff0c;内部维护FIFO双向队列&#xff08;双向链表实现&#xff09;。 AQS重要属性&#xff1a; // 表示同步状态。它既可以表…...

4 种修复 IPhone 备份输入密码解锁的方法

您是否在 iTunes 中遇到过这样的消息&#xff1a;“输入密码以解锁您的 iPhone 备份”&#xff1f;出现这种情况是因为备份具有加密备份。当您通过 iTunes 为 iPhone 创建此备份时&#xff0c;您需要生成 iTunes 备份密码来保护和加密您的 iPhone 备份。当您想要更改 iPhone 备…...

选课(贪心)

小明是个好学的程序猿&#xff0c;他想在一天内尽可能多的选择课程进行学习。在下列课程中&#xff0c;他能选择的最多课程是几门&#xff1f; 输入格式: 第一行为一个整数n&#xff0c;表示课程总数。接下来每行为x&#xff0c;y&#xff0c;z表示课程名&#xff0c;开始时间…...

【深度学习】Java DL4J基于 LSTM 构建新能源预测模型

🧑 博主简介:CSDN博客专家,历代文学网(PC端可以访问:https://literature.sinhy.com/#/?__c=1000,移动端可微信小程序搜索“历代文学”)总架构师,15年工作经验,精通Java编程,高并发设计,Springboot和微服务,熟悉Linux,ESXI虚拟化以及云原生Docker和K8s,热衷于探…...

【linux基础I/O(1)】文件描述符的本质重定向的本质

目录 前言1. 理解C语言的文件接口2. 操作文件的系统调用接口2.1 open函数详解2.2 close函数详解2.3 write函数详解2.4 read函数详解 3. 文件描述符fd详解4. 文件描述符的内核本质5. 怎样理解Linux下一切皆文件?6. 理解输出输入重定向7. 重定向的系统调用8. 总结 前言 “在Lin…...

微服务架构下的慢请求排查与优化策略

目录 一、分析请求路径 二、检查日志 三、进行时序分析 四、检查资源消耗 五、检查并发处理能力 六、检查网络连接 七、从根本上使用服务治理的方式解决问题 八、结语 在当今的数字化时代&#xff0c;企业为了应对快速变化的市场需求和日益增长的用户基数&#xff0c;纷…...

C++ 中 Unicode 字符串的宽度

首先&#xff0c;什么是 Unicode&#xff1f; Unicode 实际上是一个统一的文字编码标准&#xff0c;它出现目的是为了解决不同计算机之间字符编码不同而导致的灾难性不兼容问题。 Unicode 字符集与 Unicode 编码是两种不同的概念。Unicode 字符集实际是对进入标准的所有文字用…...

人工智能在SEO中的应用与关键词优化策略

内容概要 随着科技的迅猛发展&#xff0c;人工智能在搜索引擎优化&#xff08;SEO&#xff09;中的应用逐渐成为业界关注的热点。AI技术不仅可以有效提高关键词的优化策略&#xff0c;还能在提升内容效率、增强用户体验方面发挥重要作用。通过对相关技术的深入探讨&#xff0c…...

spring mvc源码学习笔记之四

pom.xml 内容如下 <?xml version"1.0" encoding"UTF-8"?> <project xmlns"http://maven.apache.org/POM/4.0.0"xmlns:xsi"http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation"http://maven.apache.org/P…...

ruckus R510升级到Unleashe后不能访问

ruckus R510 是IPQ4019&#xff0c;升级到Unleashe&#xff0c;它弹窗提示 但是这个IP没办法用&#xff0c;访问不了AP。 必应了一下&#xff0c;官方提示用advance ip scanner扫描。 扫描持续好久&#xff0c;发现IP竟然是从主路由获得。 9090的端口不用填&#xff0c;甚至不…...

【游戏设计原理】47 - 超游戏思维

对于这条原理&#xff0c;我首先想到的是开放世界&#xff0c;或者探索性游戏&#xff0c;这是最能包容各类玩家的游戏类型。这类游戏定义了基本规则&#xff0c;玩家的可操作性很强。就像上图里的沙池一样&#xff0c;里面有滑梯&#xff0c;是规则性比较明确的&#xff0c;而…...

FastAPI vs Flask 专业对比与选择

FastAPI与Flask是两个流行的Python Web框架&#xff0c;它们在构建Web应用程序和API方面各有特点。以下是对这两个框架的详细比较&#xff1a; 一、设计理念与用途 Flask&#xff1a; 是一个轻量级的Python Web框架&#xff0c;基于Werkzeug WSGI工具箱和Jinja2模板引擎。设计…...

【信息系统项目管理师】【综合知识】【备考知识点】【思维导图】第十一章 项目成本管理

word版☞【信息系统项目管理师】【综合知识】【备考知识点】第十一章 项目成本管理 移动端【思维导图】☞【信息系统项目管理师】【思维导图】第十一章 项目成本管理...

xdoj-字符串-556,为什么字符不能被正常读入

目录 题目 代码 测试用例 the input the correct output 问题发现过程阐述 如果把line16中的数组大小11换成line17中的10 case 1 case 2 case 3 如果数组开成11 case4 代码分析 问题描述 Question1 Question2 题目 题目&#xff1a;连续数字字符串提取 问题描述…...

计算机网络——期末复习(5)期末考试样例1(含答案)

考试题型&#xff1b; 概念辨析&#xff15;个、计算与分析&#xff13;个、综合题&#xff13;&#xff0d;&#xff14;个 必考知识点&#xff1a; 概述&#xff1a;协议 体系结构 物理层&#xff1b;本次考核较少 链路层&#xff1a;CSMA/CD 退避二进制算法 &#xff0…...

Docker安装oracle数据库【最新版】

文章目录 1. 安装 Docker 环境2. 拉取 Oracle 镜像3. 查看镜像4. 创建容器5. 进入容器进行配置6. 进行软连接7. 配置 Oracle 环境变量8. 创建软连接9. 切换到 Oracle 用户10. 登录 SQL*Plus 并修改 sys、system 用户密码11. 重新启动数据库12. 解决 "Database Not Open&qu…...

基于STM32的智能门锁系统设计

目录 引言系统设计 硬件设计软件设计系统功能模块 用户身份验证模块开锁控制模块状态监控与报警模块数据存储与管理模块控制算法 用户身份验证算法开锁控制算法状态监控与报警算法代码实现 用户身份验证模块实现开锁控制模块实现状态监控模块实现系统调试与优化结论与展望 1. …...

【踩坑指南:2025年最新】如何在Linux(Ubuntu)启动第一个Scala Hello World程序(Scala3)

如何正确地写出Scala的第一个程序&#xff0c;并且利用Scala3的简洁特性&#xff1f; 在解释器中直接输出Hello world非常简单&#xff0c;只需要直接执行即可&#xff1a; scala> println("Hello World") Hello World 但如果我们希望编写一个脚本文件&#xf…...

SAP系统中的标准价、移动平均价是什么?有何区别?物料分类账的优点

文章目录 前言一、SAP系统中的价格控制二、移动平均价、标准价是什么&#xff1f;三、S价&#xff08;标准价&#xff09;的优势四、S价&#xff08;标准价&#xff09;的劣势五、V价&#xff08;移动平均价&#xff09;的优势六、V价&#xff08;移动平均价&#xff09;的劣势…...

9.类的定义与使用

类的定义构造函数(__init__)实例变量类变量方法(实例方法)类方法(classmethod)静态方法(staticmethod)属性装饰器(property)私有属性与方法继承多态方法重写super()函数类的文档字符串类的属性和方法访问控制 1.类的定义: 如int,list,tuple等等都是类,还可以通过class方法自己…...

浅谈 React Hooks

React Hooks 是 React 16.8 引入的一组 API&#xff0c;用于在函数组件中使用 state 和其他 React 特性&#xff08;例如生命周期方法、context 等&#xff09;。Hooks 通过简洁的函数接口&#xff0c;解决了状态与 UI 的高度解耦&#xff0c;通过函数式编程范式实现更灵活 Rea…...

VB.net复制Ntag213卡写入UID

本示例使用的发卡器&#xff1a;https://item.taobao.com/item.htm?ftt&id615391857885 一、读取旧Ntag卡的UID和数据 Private Sub Button15_Click(sender As Object, e As EventArgs) Handles Button15.Click轻松读卡技术支持:网站:Dim i, j As IntegerDim cardidhex, …...

抖音增长新引擎:品融电商,一站式全案代运营领跑者

抖音增长新引擎&#xff1a;品融电商&#xff0c;一站式全案代运营领跑者 在抖音这个日活超7亿的流量汪洋中&#xff0c;品牌如何破浪前行&#xff1f;自建团队成本高、效果难控&#xff1b;碎片化运营又难成合力——这正是许多企业面临的增长困局。品融电商以「抖音全案代运营…...

【项目实战】通过多模态+LangGraph实现PPT生成助手

PPT自动生成系统 基于LangGraph的PPT自动生成系统&#xff0c;可以将Markdown文档自动转换为PPT演示文稿。 功能特点 Markdown解析&#xff1a;自动解析Markdown文档结构PPT模板分析&#xff1a;分析PPT模板的布局和风格智能布局决策&#xff1a;匹配内容与合适的PPT布局自动…...

2025 后端自学UNIAPP【项目实战:旅游项目】6、我的收藏页面

代码框架视图 1、先添加一个获取收藏景点的列表请求 【在文件my_api.js文件中添加】 // 引入公共的请求封装 import http from ./my_http.js// 登录接口&#xff08;适配服务端返回 Token&#xff09; export const login async (code, avatar) > {const res await http…...

Golang——6、指针和结构体

指针和结构体 1、指针1.1、指针地址和指针类型1.2、指针取值1.3、new和make 2、结构体2.1、type关键字的使用2.2、结构体的定义和初始化2.3、结构体方法和接收者2.4、给任意类型添加方法2.5、结构体的匿名字段2.6、嵌套结构体2.7、嵌套匿名结构体2.8、结构体的继承 3、结构体与…...

用鸿蒙HarmonyOS5实现中国象棋小游戏的过程

下面是一个基于鸿蒙OS (HarmonyOS) 的中国象棋小游戏的实现代码。这个实现使用Java语言和鸿蒙的Ability框架。 1. 项目结构 /src/main/java/com/example/chinesechess/├── MainAbilitySlice.java // 主界面逻辑├── ChessView.java // 游戏视图和逻辑├──…...

如何在Windows本机安装Python并确保与Python.NET兼容

✅作者简介&#xff1a;2022年博客新星 第八。热爱国学的Java后端开发者&#xff0c;修心和技术同步精进。 &#x1f34e;个人主页&#xff1a;Java Fans的博客 &#x1f34a;个人信条&#xff1a;不迁怒&#xff0c;不贰过。小知识&#xff0c;大智慧。 &#x1f49e;当前专栏…...

麒麟系统使用-进行.NET开发

文章目录 前言一、搭建dotnet环境1.获取相关资源2.配置dotnet 二、使用dotnet三、其他说明总结 前言 麒麟系统的内核是基于linux的&#xff0c;如果需要进行.NET开发&#xff0c;则需要安装特定的应用。由于NET Framework 是仅适用于 Windows 版本的 .NET&#xff0c;所以要进…...

深入解析光敏传感技术:嵌入式仿真平台如何重塑电子工程教学

一、光敏传感技术的物理本质与系统级实现挑战 光敏电阻作为经典的光电传感器件&#xff0c;其工作原理根植于半导体材料的光电导效应。当入射光子能量超过材料带隙宽度时&#xff0c;价带电子受激发跃迁至导带&#xff0c;形成电子-空穴对&#xff0c;导致材料电导率显著提升。…...