AQS浅谈

浅谈Java的AQS 所谓AQS,指的是AbstractQueuedSynchronizer,它提供了一种实现阻塞锁和一系列依赖FIFO等待队列的同步器的框架,ReentrantLock、Semaphore、CountDownLatch、CyclicBarrier等并发类均是基于AQS来实现的,具体用法是通过继承AQS实现其模板方法,然后将子类作为同步组件的内部类。 了解一个框架最好的方式是读源码,说干就干。 AQS是... 阅读详情

Java并发包(JUC)中提供了很多并发工具,譬如ReentrangLock、Semaphore,它们的实现都用到了一个共同的基类–AbstractQueuedSynchronizer,简称AQS。
AQS是一个用来构建锁和同步器的框架,使用AQS能简单且高效地构造出应用广泛的大量的同步器。
那么今天我们就来简单的谈一谈AQS。

基本实现原理
AQS使用一个int成员变量来表示同步状态,通过内置的FIFO队列来完成获取资源线程的排队工作。

 private volatile int state;  //共享变量,使用volatile修饰保证线程可见性

这样状态信息通过procted类型的getState,setState,compareAndSetState等方法进行操作。

AQS为使用提供了底层支撑,如何组装实现,使用者可以自由发挥。
同步器的设计是基于模板方法模式的,一般的使用方式是这样:

1.使用者继承AbstractQueuedSynchronizer并重写指定的方法。(这些重写方法很简单,无非是对于共享资源state的获取和释放)

2.将AQS组合在自定义同步组件的实现中,并调用其模板方法,而这些模板方法会调用使用者重写的方法。

这其实是模板方法模式的一个很经典的应用。

我们来看看AQS定义的这些可重写的方法:

protected boolean tryAcquire(int arg)    //独占式获取同步状态,试着获取,
										//	成功返回true,反之为false
protected boolean tryRelease(int arg)  //独占式释放同步状态,等待中的其他线程此时
										//	将有机会获取到同步状态;
protected int tryAcquireShared(int arg)   //共享式获取同步状态,返回值大于等于0,
											//代表获取成功;反之获取失败;
protected boolean tryReleaseShared(int arg)   //共享式释放同步状态,成功为true,失败为false

protected boolean isHeldExclusively()    // 是否在独占模式下被线程占用。

综上所述,我们来总结一下AQS的使用:

首先,我们需要去继承AbstractQueuedSynchronizer这个类,然后我们根据我们的需求去重写相应的方法,比如要实现一个独占锁,那就去重写tryAcquire,tryRelease方法,要实现共享锁,就去重写tryAcquireShared,tryReleaseShared;最后,在我们的组件中调用AQS中的模板方法就可以了,而这些模板方法是会调用到我们之前重写的那些方法的。

下面我们用一个简单的例子来看看如何使用AQS:
Mutex类:

public class Mutex implements java.io.Serializable {
 9     //静态内部类,继承AQS
10     private static class Sync extends AbstractQueuedSynchronizer {
11         //是否处于占用状态
12         protected boolean isHeldExclusively() {
13             return getState() == 1;
14         }
15         //当状态为0的时候获取锁,CAS操作成功,则state状态为1,
16         public boolean tryAcquire(int acquires) {
17             if (compareAndSetState(0, 1)) {
18                 setExclusiveOwnerThread(Thread.currentThread());
19                 return true;
20             }
21             return false;
22         }
23         //释放锁,将同步状态置为0
24         protected boolean tryRelease(int releases) {
25             if (getState() == 0) throw new IllegalMonitorStateException();
26             setExclusiveOwnerThread(null);
27             setState(0);
28             return true;
29         }
30     }
31         //同步对象完成一系列复杂的操作,我们仅需指向它即可
32         private final Sync sync = new Sync();
33         //加锁操作,代理到acquire(模板方法)上就行,acquire会调用我们重写的tryAcquire方法
34         public void lock() {
35             sync.acquire(1);
36         }
37         public boolean tryLock() {
38             return sync.tryAcquire(1);
39         }
40         //释放锁,代理到release(模板方法)上就行,release会调用我们重写的tryRelease方法。
41         public void unlock() {
42             sync.release(1);
43         }
44         public boolean isLocked() {
45             return sync.isHeldExclusively();
46         }
47 }

TestMutex.java:

public class TestMutex {
 9     private static CyclicBarrier barrier = new CyclicBarrier(31);
10     private static int a = 0;
11     private static  Mutex mutex = new Mutex();
12 
13     public static void main(String []args) throws Exception {
14         //说明:我们启用30个线程,每个线程对i自加10000次,同步正常的话,最终结果应为300000;
15         //未加锁前
16         for(int i=0;i<30;i++){
17             Thread t = new Thread(new Runnable() {
18                 @Override
19                 public void run() {
20                     for(int i=0;i<10000;i++){
21                         increment1();//没有同步措施的a++;
22                     }
23                     try {
24                         barrier.await();//等30个线程累加完毕
25                     } catch (Exception e) {
26                         e.printStackTrace();
27                     }
28                 }
29             });
30             t.start();
31         }
32         barrier.await();
33         System.out.println("加锁前,a="+a);
34         //加锁后
35         barrier.reset();//重置CyclicBarrier
36         a=0;
37         for(int i=0;i<30;i++){
38             new Thread(new Runnable() {
39                 @Override
40                 public void run() {
41                     for(int i=0;i<10000;i++){
42                         increment2();//a++采用Mutex进行同步处理
43                     }
44                     try {
45                         barrier.await();//等30个线程累加完毕
46                     } catch (Exception e) {
47                         e.printStackTrace();
48                     }
49                 }
50             }).start();
51         }
52         barrier.await();
53         System.out.println("加锁后,a="+a);
54     }
55     /**
56      * 没有同步措施的a++
57      * @return
58      */
59     public static void increment1(){
60         a++;
61     }
62     /**
63      * 使用自定义的Mutex进行同步处理的a++
64      */
65     public static void increment2(){
66         mutex.lock();
67         a++;
68         mutex.unlock();
69     }
70 }

最后的运行结果:

加锁前,a=279204
加锁后,a=300000
《YOLOv8:从入门到实战》专栏介绍 & 专栏目录 本专栏涵盖了丰富的YOLOv8算法从入门到实战系列教程,专为学习YOLOv8的同学而设计,堪称全网最详细的教程!🌈🌈🌈 阅读详情

相关推荐

SystemVue 链路预算、仿真分析步骤

使用SystemVue进行链路预算、频谱分析等,相对ADS更全面。

BeCourageable的博客 3836

【Java多线程】浅谈AQS抽象队列同步器

文章目录1. AQS 简介2. AQS 的数据结构3. 资源共享模式4. AQS 的主要方法源码解析4.1 获取资源4.2 释放资源 1. AQS 简介 AQS 是 AbstractQueuedSynchronizer 的简称,即「抽象队列同步器」,从字面意思上理解: 抽象:抽象类,只实现一些主要逻辑,有些方法由子类实现; 队列:使用先进先出(FIFO)队列存储数据; 同步:实现了同步的功能。 那 AQS 有什么用呢?AQS 是一个用来构建锁和同步器的框架,使用 AQS 能简单且高效地构造出应用广泛的同

aaa_hao的博客 772

从药企研发视角:如何用GNN提升分子水溶性预测准确率?PyTorch+ESOL全案例

本文从药企研发的实际需求出发,详细介绍了如何利用图神经网络(GNN)技术,结合PyTorch框架和ESOL数据集,构建并优化分子水溶性预测模型。通过完整的代码案例,深入探讨了分子图数据处理、GNN架构设计、超参数调优以及模型评估与解释等关键环节,旨在帮助研发团队提升预测准确率,从而更高效地筛选和优化候选药物分子。

weixin_29054399的博客 292

浅谈AQS

说到Java的并发编程包,就一定少不了一个东西,它就是AQS,可能有些同学是第一次遇到这个名词,没关系,并发包里的ReentrantLock你总用过吧?那么你有没有想过,为什么简简单单地调用lock()、unlock()方法就能够解决线程的安全问题呢? CAS 我们都知道,Java还有一种线程同步的方式,synchronized关键字,使用它能够解决线程的安全问题,然而,由于synchronized底层是通过操作系统Mutex Lock来实现的,导致synchronized的效率比较低,被大家称为重量级锁。

。。。 808

Windows本地部署Qwen3-14B实战指南:Ollama+Open WebUI零Docker方案

大语言模型本地部署是AI工程化落地的关键环节,其核心在于推理框架兼容性、硬件加速适配性与端到端稳定性。Ollama作为轻量级模型运行时,原生支持Windows DirectML与CUDA,规避了Docker/WSL2虚拟化开销和llama.cpp编译风险;Qwen3-14B则凭借128K上下文、Tool Calling原生支持及中文长文本结构化能力,成为政务、金融等场景首选。本文聚焦Windows平台真实约束——显存阈值、驱动版本匹配、路径编码兼容、离线知识库集成(RAG)等工程细节,提供经63台Windo

weixin_32136203的博客 413

IC设计新手必看:如何正确使用去耦电容(decap)避免电源噪声?

本文深入探讨了IC设计中去耦电容(decap)的应用技巧,从核心原理到布局实现,帮助新手工程师有效抑制电源噪声。文章详细解析了MIM、MOM等电容类型的特性与选择策略,并提供了先进的布局技巧和验证方法,特别适用于28nm以下先进工艺的电路设计挑战。

weixin_30555125的博客 114

谈谈你对AQS的理解。AQS如何实现可重 入锁?

aqs

zwb的博客 1559

硅纪元应用测评 | AI搜索引擎大比拼:360AI搜索、秘塔搜索、GenSpark AI和天工AI对比评测

搜索引擎输出的每个段落都有对应的出处,如果有错误,也是信息源的问题,从普通用户的角度来看,这与AI搜索的产品关系不大,能让用户对AI搜索的服务和得到的信息有一个隔离。同时,提供更多的定制选项,允许用户根据自己的偏好调整搜索结果的权重和排序,将使得搜索体验更加个性化和满足用户的具体需求。此外,大部分搜索工具还提供了一个无广告的搜索环境(360AI搜索部分内容会有广告),极大地提升了用户的搜索体验。AI搜索的本质依然是搜索,但它通过AI的逻辑分析和语言重新组织,使用户能够快速得到想要的信息。

guijiyuantech的博客 2013

AbstractQueuedSynchronizer类原理剖析

少不入川,老不思蜀。

少不入川。的博客 304

【华为OD机试真题 2025C卷新题】855、识文断句 | 机试真题+思路参考+代码分析(C++、Java、Py、C语言、JS)

【华为OD机试真题 2025C卷新题】855、识文断句 | 机试真题+思路参考+代码分析(C++、Java、Py、C语言、JS) 华为od机试,华为od机试真题,华为od机试E卷,华为odE卷,华为od机试真题E卷,华为OD,华为OD机试,华为OD机试真题,华为od机考,华为od机试D卷,华为od机试真题D卷,华为od手撕代码,华为od,华为od机试C卷,华为od e卷,华为2025e卷,od机试,2025E卷,华为OD机试E卷,什么是华为od,华为od介绍,全面了解华为od,2025华为od,如何备战华为

KJ.JK 1851

Open3D 点云DBSCAN聚类算法

DBSCAN(Density-Based Spatial Clustering of Applications with Noise)是一种基于密度的聚类算法,能够识别任意形状的聚类,并处理噪声数据。

纵马踏花向自由 1835

ReentrantLock及AQS浅谈

AQS全称AbstractQueuedSynchronizer,是java并发包中的一个类,该类更像是一个框架,提供了一些模板方法供子类实现,从而实现了不同的同步器,如下图所示。ReentrantLock,ReentrantReadWriteLock,ThreadPoolExecutor这些常见类都使用了AQS。

网易云捕博客 668

RK3566 Android11默认客户Launcher修改

【代码】RK3566 Android11默认客户Launcher修改。

Android系统开发笔记 1723

浅谈Java之AQS

1.什么是AQS AQS是java.util.concurrent.locks.AbstractQueuedSynchronizer类的缩写,顾名思义 :抽象的队列同步器,是著名的java多线程开发大佬:李狗哥(Doug Lea)的佳作,aqs是用来构建锁或者其他同步组件(信号量、事件等)的基础框架类,它维护了一个volatile int state(代表共享资源)和一个FIFO线程等待队列(多...

BQGLHL的博客 511

C# WinForm 基于DirectShow.dll编写的程序,可边预览边保存视频,音频和图片

基于微软的DirectShow.dll的二次开发1.自动识别连接的摄像头跟麦克风且可以对其进行选择(默认选中第一个)2.可录制wmv和avi两种格式的视频并且都带有音频,avi可以录制的分辨率和帧数进行选择,wmv默认进行了淸晰度优化如不喜欢可去除代码中有相关提示3.可在预览点开之后进行拍照,也可边录制视频边拍照4.添加了视频和音频的压缩功能(酌情使用)这次二次开发发现C#对DirectShow的相关信息太少,这次做完也不敢藏私共享出来,还望大家指正

ET2012新版免狗免安装绿色软件

ET2012新版免狗免安祖昂绿色软件。,新界面,新视觉,

aqs java_【转载】浅谈Java的AQS

所谓AQS,指的是AbstractQueuedSynchronizer,它提供了一种实现阻塞锁和一系列依赖FIFO等待队列的同步器的框架,ReentrantLock、Semaphore、CountDownLatch、CyclicBarrier等并发类均是基于AQS来实现的,具体用法是通过继承AQS实现其模板方法,然后将子类作为同步组件的内部类。了解一个框架最好的方式是读源码,说干就干。AQS是JD...

weixin_42513632的博客 320

Statistics and Machine Learning Toolbox

Statistics and Machine Learning Toolbox(带书签),MATLAB统计学习工具

浅谈AQS的基本原理

AQS设置为抽象类的原因是它必须要实现其中的某一些方法才能使用,比如tryAcquire,tryRelease等核心方法,作者可能并不希望使用者直接初始化AQS并使用,所以使用abstract修饰。

BASK2311的博客 884

OV9734 DATASHEET,完整规格书

OV9734完整规格书,包括电气参数,尺寸规格,寄存器配置表等

浅谈对AQS的理解

AQS是reentranctLock、syclicBarrier、CountDownLatch、CountDownLatch等锁的基础; 一句话概括: AQS是由一个volatile修饰的state和监控这个state的双向链构成,双项链每个节点是一个Node,每一个Node对应一个线程;通过tryAcquire()、compareAndSetSate()来获取锁; 分析源码(debug一下一步步走看看),记录一下(个人记录): ...

qq_21223653的博客 689

线程CAS AQS浅谈

线程CAS AQS浅谈面试必备,适合快速上手理解。

qq_43081106的博客 492

浅谈AQS --JAVA

一 AQS能干什么 AQS是对列同步器AbustactQueuedSynchronizer的简称,位于juc包下。 你所看见的锁包括 ReentrantLock、ReentrantReadWriteLock,还有同步组件 CyclicBarrier等,它的内部都是通过AQS实现的。通过学习AQS,你可以写出自己的锁与同步组件。 二AQS内部实现 1.同步队列(一个FIFO双向队列) ...

qq_36647176的博客 395

浅谈AQS(AbstractQueuedSynchronizer)

AQS AQS(AbstractQueuedSynchronizer)即队列同步器,提供了一种实现阻塞锁和一系列依赖FIFO等待队列的同步器的框架,ReentrantLock、Semaphore、CountDownLatch、CyclicBarrier等并发类均是基于AQS来实现的,具体用法是通过继承AQS实现其模板方法,然后将子类作为同步组件的内部类。 AQS维护了一个volatile语义(支持多线程下的可见性)的共享资源变量state和一个FIFO线程等待队列(多线程竞争state被阻塞时会进入此队

178

【Java多线程】浅谈AQS

浅谈AQS(AbstractQueuedSynchronizer)一、简介二、源码分析三、总结 一、简介 AQS全称AbstractQueuedSynchronizer,在java中多线程工具包JUC是基于AQS实现的 技术核心:共享(volatile)state + 双向链表 实现方法:CAS操作 设计模式:模板模式(Template Pattern):父类画模,子类重写 二、源码分析...

阿磊的博客 319
上一篇: Action中的动态方法调用简单示例——登录注册系统
下一篇: Struts2的标签库详解(一)
monkey_wei
博客等级 码龄8年 62粉丝 139原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值