java——AQS(AbstractQueuedSynchronizer)

为了带你精通 Java AQS,我画了 40 张图,从管程模型讲起! AQS 使用 FIFO 队列实现了一个锁相关的并发器模板,可以基于这个模板来实现各种锁,包括独占锁、共享锁、信号量等。AQS 中,有一个核心状态是 waitStatus,这个代表节点的状态,决定了当前节点的后续操作,比如是否等待唤醒,是否要唤醒后继节点。AQS 基于双向队列实现了入口等待队列,基于 state 变量实现了各种并发锁,上篇文章讲了入口等待队列,而这篇文章主要讲了基于 AQS 的并发锁原理。 阅读详情
AI摘要

AQS是Java并发包中的核心组件,是构建锁和其他同步器的基础框架。本文详细介绍了AQS的基本概念、核心组件、工作原理、资源共享方式、应用场景、优缺点,并给出示例。它支持独占和共享两种资源共享方式,广泛应用于Java并发编程。

AQS(AbstractQueuedSynchronizer)是Java并发包(java.util.concurrent)中的一个核心组件,是构建锁和其他同步器的基础框架。以下是对AQS的详细理解:

一、AQS的基本概念

AQS,全称为AbstractQueuedSynchronizer,是一个抽象的队列式同步器。它定义了一套多线程访问共享资源的同步器框架,为Java并发同步组件提供统一的底层支持。AQS是一个为各个同步组件提供基本框架的抽象类,其内部实现了同步状态的管理和线程的排队机制。

二、AQS的核心组件

  1. 同步状态:AQS使用一个int类型的成员变量来表示同步状态。这个状态变量是线程共享的资源,通过内置的FIFO队列(先进先出队列)来完成获取资源线程的排队工作。
  2. FIFO队列:AQS的底层实现是一个双向链表,用于管理等待获取同步状态的线程。当线程无法获取同步状态时,会被加入到这个队列中等待。
  3. CLH队列锁:AQS使用CLH队列锁来实现线程的阻塞等待和唤醒机制。CLH是一个虚拟的双向队列,即不存在队列实例,仅存在节点之间的关联关系。

三、AQS的工作原理

  1. 获取同步状态:当线程尝试获取同步状态时,会调用AQS的tryAcquire方法(对于独占模式)或tryAcquireShared方法(对于共享模式)。如果成功获取到同步状态,则返回true;否则,线程会被加入到等待队列中。
  2. 释放同步状态:当线程释放同步状态时,会调用AQS的tryRelease方法(对于独占模式)或tryReleaseShared方法(对于共享模式)。这些方法会修改同步状态的值,并可能唤醒等待队列中的线程。
  3. 线程排队与唤醒:等待获取同步状态的线程会被加入到FIFO队列中,并按照队列的顺序等待。当某个线程释放同步状态时,会唤醒队列中的下一个线程来尝试获取同步状态。

四、AQS的资源共享方式

AQS支持两种资源共享方式:独占(Exclusive)和共享(Share)。

  1. 独占:只有一个线程能执行,如ReentrantLock。独占锁又可分为公平锁和非公平锁。公平锁按照线程在队列中的排队顺序来获取锁,非公平锁则允许线程无视队列顺序直接去抢锁。
  2. 共享:多个线程可同时执行,如Semaphore、CountDownLatch、CyclicBarrier等。共享锁允许多个线程同时访问共享资源。

五、AQS的应用场景

AQS广泛应用于Java并发编程中,是实现各种同步机制的基础。例如,ReentrantLock、Semaphore、CountDownLatch等同步器都是基于AQS实现的。通过扩展AQS,开发者可以实现各种复杂的同步器,以满足不同的并发编程需求。

六、AQS的优缺点

优点:

  1. 提供了统一的同步器框架,简化了同步器的实现过程。
  2. 使用了FIFO队列来管理等待线程,保证了线程的公平性。
  3. 提供了灵活的资源共享方式,支持独占和共享两种模式。

缺点:

  1. AQS是一个相对复杂的框架,需要开发者对其内部机制有一定的了解才能正确使用。
  2. 在某些情况下,AQS的性能可能不如一些定制的同步器。

七、AQS示例

import java.util.concurrent.locks.AbstractQueuedSynchronizer;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.LockSupport;

// 自定义锁类
class MyLock implements Lock {
    // 静态内部类,继承AQS
    private static class Sync extends AbstractQueuedSynchronizer {
        // 是否处于独占模式
        protected boolean isHeldExclusively() {
            return getState() == 1;
        }

        // 尝试获取锁,当状态为0时获取锁成功
        public boolean tryAcquire(int acquires) {
            assert acquires == 1; // 只允许获取1个单位的锁
            if (compareAndSetState(0, 1)) {
                setExclusiveOwnerThread(Thread.currentThread());
                return true;
            }
            return false;
        }

        // 尝试释放锁,将状态设置为0
        protected boolean tryRelease(int releases) {
            assert releases == 1; // 只允许释放1个单位的锁
            if (getState() == 0) throw new IllegalMonitorStateException();
            setExclusiveOwnerThread(null);
            setState(0);
            return true;
        }

        // 提供条件变量
        Condition newCondition() { return new ConditionObject(); }
    }

    // 将操作代理到Sync上
    private final Sync sync = new Sync();

    // 实现Lock接口的方法
    @Override
    public void lock() {
        sync.acquire(1);
    }

    @Override
    public void lockInterruptibly() throws InterruptedException {
        sync.acquireInterruptibly(1);
    }

    @Override
    public boolean tryLock() {
        return sync.tryAcquire(1);
    }

    @Override
    public boolean tryLock(long time, TimeUnit unit) throws InterruptedException {
        return sync.tryAcquireNanos(unit.toNanos(time));
    }

    @Override
    public void unlock() {
        sync.release(1);
    }

    @Override
    public Condition newCondition() {
        return sync.newCondition();
    }

    public static void main(String[] args) {
        MyLock lock = new MyLock();

        Runnable task = () -> {
            lock.lock();
            try {
                System.out.println(Thread.currentThread().getName() + " 获取锁");
                // 模拟任务执行
                LockSupport.parkNanos(TimeUnit.SECONDS.toNanos(1));
            } finally {
                System.out.println(Thread.currentThread().getName() + " 释放锁");
                lock.unlock();
            }
        };

        Thread t1 = new Thread(task, "Thread-1");
        Thread t2 = new Thread(task, "Thread-2");

        t1.start();
        t2.start();
    }
}
  1. MyLock类:实现Lock接口,内部包含一个静态内部类Sync,该内部类继承自AbstractQueuedSynchronizer。
  2. Sync类:
    • isHeldExclusively:判断当前线程是否持有锁。
    • tryAcquire:尝试获取锁,如果当前状态为0(表示锁未被持有),则通过compareAndSetState方法将状态设置为1,并设置当前线程为独占线程。
    • tryRelease:尝试释放锁,将状态设置为0,并清除独占线程。
    • newCondition:创建一个条件变量。
  3. MyLock方法:将Lock接口的方法代理到Sync对象上。
  4. main方法:创建两个线程,每个线程尝试获取和释放锁,模拟任务执行。
Gemini永久会员 Java AQS (AbstractQueuedSynchronizer) 实现流程图 AQS 通过这些机制实现了灵活的同步器构建框架,ReentrantLock、CountDownLatch、Semaphore 等同步工具都是基于 AQS 实现的。将节点加入同步队列尾部。前驱节点是否为头节点?设置为头节点并清除数据。线程尝试获取同步状态。同步状态是否可获取? 阅读详情

相关推荐

(面经总结)一篇文章带你完整复习 Java 中的 AQS

文章目录一、什么是AQS二、AQS的原理三、state:状态四、AQS共享资源的方式:独占式和共享式 一、什么是AQS AQS(Abstract Queued Synchronizer)是一个抽象的队列同步器,通过维护一个共享资源状态(Volatile Int State)和一个先进先出(FIFO)的线程等待队列来实现一个多线程访问共享资源的同步框架。 二、AQS的原理 AQS为每个共享资源都设置一个共享资源锁,线程在需要访问共享资源时首先需要获取共享资源锁,如果获取到了共享资源锁,便可以在当前线程中使用该

南淮北安的博客 2016

Java并发-AQS及各种Lock锁的原理

 AQS是AbstractQueuedSynchronizer的简称。AQS提供了一种实现阻塞锁和一系列依赖FIFO等待队列的同步器的框架,如下图所示。AQS为一系列同步器依赖于一个单独的原子变量(state)的同步器提供了一个非常有用的基础。子类们必须定义改变state变量的protected方法,这些方法定义了state是如何被获取或释放的。鉴于此,本类中的其他方法执行所有的排队和阻塞机制。子...

phcgld1314的博客 608

Java并发编程之AQS

AQS是AbstractQueueSynchronizer是缩写,其意思就是抽象队列同步器。原理就是通过一个FIFO队列维护一个state同步状态值,只需要继承该抽象类重写对应的方法便可实现一套线程同步机制。AQS抽象类在java.util.concurrent.locks包下定义。如上图所示,AQS属于一个抽象类,主要是用来构建锁结构以及同步器的一个抽象类。AQS继承了AbstractOwnableSynchronizer,其作用为设置和获取独占锁的拥有者线程方法。

天天新知 2379

Java知识学习13(AQS详解)

JavaSE

ldy007714的博客 3523

【深入理解Java原理】AQS(AbstractQueuedSynchronizer)

Java并发 -AQS AQS 是啥? AQS的全称为(AbstractQueuedSynchronizer) 即队列同步器。它是构建锁及其他同步组件的基础框架(如 ReetrantLock, ReetrantReadWriteLock,Semaphore等) AQS 提供了哪些方法? ...

王小明的专栏 822

Surface Pro 4/5/6/7保姆级黑苹果安装:从Windows分区到OC引导配置全流程(含EFI文件替换避坑)

本文详细介绍了在Surface Pro 4/5/6/7上安装黑苹果的全流程,包括Windows分区、OC引导配置和EFI文件替换等关键步骤。通过实战经验分享,帮助用户避开常见陷阱,实现Windows与macOS双系统完美共存,特别适合对黑苹果安装感兴趣的Surface Pro用户。

weixin_30300225的博客 1359

Java AQS(AbstractQueuedSynchronizer)详解

java,AQS

@chen 829

uniCloud云存储进阶:七牛云扩展存储从开通、绑定域名到批量上传的完整实战

本文详细介绍了uniCloud云存储进阶实践,重点讲解如何通过七牛云扩展存储实现从开通、绑定域名到批量上传的完整流程。内容涵盖成本优势分析、域名备案方案、SSL证书配置、多文件并发上传控制等实战技巧,并提供可直接复用的代码示例,帮助开发者高效构建内容社区类应用。

weixin_26985923的博客 468

Java并发之AbstractQueuedSynchronizer(AQS)详解

何为AQS?AQS 的全称为 AbstractQueuedSynchronizer,翻译抽象队列同步器。AQS定义了多线程访问共享资源同步器框架,许多同步类实现都依赖于它,这个类在 java.util.concurrent.locks 包下面。​AQS 就是一个抽象类,主要用来构建锁和同步器。 AQS 为构...............

陈橘又青的博客 2万+

Zenoh:统一数据平面协议,重塑物联网与边缘计算架构

在分布式系统与物联网领域,数据通信与处理常面临协议割裂的挑战。传统方案如MQTT、Kafka、gRPC等,分别针对发布/订阅、流处理和RPC等不同场景,导致架构复杂、集成成本高。其核心问题在于未能统一处理“运动中数据”(Data in Motion)与“静止中数据”(Data at Rest)。Zenoh协议通过创新的“Key-Value”寻址与“Selector”查询语言,将发布/订阅、存储、查询和计算四种核心操作融合进单一协议,构建了统一的抽象层。这种设计实现了极低的协议开销(仅5字节头部)和地理分布式

weixin_29597551的博客 290

用Python写个彩票小助手:自动生成双色球/大乐透号码并保存到桌面

本文介绍如何使用Python开发一个智能彩票助手,实现双色球和大乐透号码的随机生成与桌面文件保存功能。通过详细的代码示例,包括随机号码生成、文件操作、用户交互和错误处理,帮助Python初学者快速掌握实用工具开发技巧。

weixin_42566121的博客 515

【Java 并发】AbstractQueuedSynchronizer (AQS) 初识

在源码中, 对 AQS 的解释 (可以查看 AbstractQueuedSynchronizer 的类注释)提供了一个框架, 用于实现依赖于先进先出 (FIFO) 的等待队列的阻塞锁和相关的同步器 (例如: 信号量, 事件等)。这个类是被设计用来作为一个有用的基础, 为大部分的依靠一个单独的原子变量来表示状态的同步器。AQS (同步器) 是用来构建锁和其他同步组件的基础框架, 它的实现主要依赖一个int 成员变量来表示同步状态以及通过一个FIFO 队列构成等待队列。

LCN29的博客 1076

滑模控制算法——基本原理(附MATLAB程序)

选择一个滑模面和是设计参数。是滑模面函数,通常我们希望系统状态在的面上滑动。我们以一个简单的二阶系统作为示例,其状态空间方程为:是系统矩阵是输入矩阵是输出矩阵假设我们的系统如下:滑模控制算法的核心在于设计合适的滑模面和控制律,并分析系统在滑模面上的稳定性。通过上述公式和步骤,可以有效地设计滑模控制器,以处理具有非线性和不确定性的动态系统。总的来说,滑模控制算法因其鲁棒性和灵活性在处理复杂控制问题中表现出色,但在实际应用中需要精心设计以克服抖振现象和其他潜在问题。BuxuABDC。

qq_35623594的博客 2万+

Java AQS(AbstractQueuedSynchronizer)

文章目录什么是 AQS?AQS 核心思想自定义 AQSAQS 源码分析ReentrantLock 与 AQSReentrantLock 加锁流程条件变量实现原理同步方案对比ReentrantReadWriteLock 读写锁CyclicBarrier 和 CountDownLatch 什么是 AQS? AQS(AbstractQueuedSynchronizer),位于 java.util.concurrent.locks 包下的一个类,它是 jdk 1.5 提供的一套用于实现阻塞锁和一系列依赖 FIFO(

Vincent的博客 814

MWORKS 2025a电气模型库实战:手把手教你搭建全桥LLC电路(附避坑指南)

本文详细介绍了如何使用MWORKS 2025a电气模型库搭建全桥LLC电路,包括环境准备、电路拓扑构建、参数优化及故障诊断。通过实战案例和避坑指南,帮助电源工程师高效设计谐振转换器,提升转换效率至98%以上。文章特别强调了Modelica模型库在电气系统建模中的关键作用。

s8t9u0v1w的博客 603

C#身份验证黑科技:用量子级加密与多维防御矩阵构建坚不可摧的用户管理系统!

某金融系统因身份验证漏洞导致200万用户数据泄露,量子级防御可将攻击面缩小99.99%。

墨夶的博客 352

Java AQS(AbstractQueuedSynchronizer)深入解析

AQS全称为,翻译为“抽象队列同步器”。它是 Java 并发包中的一个重要类,提供了一种框架,用于构建锁和同步器。AQS 的核心思想是通过维护一个线程的等待队列来实现线程间的同步。AQS 提供了强大的同步机制,能够帮助开发者轻松实现复杂的线程同步需求。通过理解其核心原理和具体实现类,可以更有效地利用 Java 的并发工具,提高应用程序的性能和可靠性。

weixin_58316280的博客 1138

基于GA-BP遗传算法优化神经网络的多输入多输出数据预测-Python代码实现

多输入多输出的GA-BP神经网络

2301_80449389的博客 2306

Java之AQS(AbstractQueuedSynchronizer)

AQS 的全称为,翻译过来的意思就是抽象队列同步器。这个类在包下面。● 是用来实现锁或者其他同步器组件的公共基础部分的抽象实现● 是重量级基础框架及整个JUC体系的基石,主要用于解决锁分配给”谁“的问题。● 整体就是一个抽象的FIFO队列来完成资源获取线程的排队工作,并通过一个int类变量表示持有锁的状态。

qq_62592925的博客 1047

WINCC7.3破解文件

WINCC7.3硬件够破解文件,有需要的下载!WINCC7.3硬件够破解文件,有需要的下载!

数学建模模型总结

这是本人在两年内准备参加数学建模竞赛搜集到的模型资料,已经经过了本人的筛选和整理,希望能够对准备参加数学建模竞赛的学弟学妹们提供一些帮助!

Java并发编程-AbstractQueuedSynchronizer (AQS) 解读

AQS是 Java 并发包中的一个核心类,用于构建锁和其他同步器(如信号量、倒计时闩锁等)的基础框架,是实现 ReentrantLock、ReadWriteLock、CountDownLatch、Semaphore 等同步器的基础。AQS 通过一个内置的 FIFO 队列来管理线程的排队和同步状态。// 等待队列的头节点// 等待队列的尾节点// 同步状态// 获取同步状态// 设置同步状态// 使用 CAS 设置同步状态// 其他属性和方法...

WenZhang的博客 1039

NTscan扫描工具

ntscan是一个扫描器,可以扫描没有密码和弱密码的共享,先到配置文件中填写猜测的用户名和密码,扫描过程中右侧出现的是扫描日志。

JAVA进阶之路-AbstractQueuedSynchronizer(AQS)源码走读

1.AQS介绍 AbstractQueuedSynchronizer是JUC的lock包实现的基石,内部通过一个int成员变量表示同步状态,也有一个是通过long实现的版本,但是int基本够用。这个state被volatile修饰保证了各个线程之间的可见性。内部通过一个内置的FIFO队列来完成资源获取线程的排队工作。 内部状态state和等待队列的head和尾节点tail通过使用volatile关...

689

Java AbstractQueuedSynchronizer(AQS)浅析之一

本篇文章对Java中的AbstractQueuedSynchronizer(AQS)进行分析和学习。若有不正之处请多多谅解,并欢迎批评指正。 为叙述方便,下文都以AQS替代AbstractQueuedSynchronizer。 使用的Java版本 src git:(master) ✗ java -version java version "1.8.0_201" Java(TM) SE Runti...

leilifengxingmw的博客 361

带你了解JAVA中的AQS介绍(AbstractQueuedSynchronizer)

带你了解JAVA中的AQS介绍(AbstractQueuedSynchronizer)

YmovomY的博客 1278

Java同步框架AbstractQueuedSynchronizer(AQS)原理分析

一、引言 AbstractQueuedSynchronizer(以下简称AQS)是一个用于构建锁或其它同步工具的基础框架。它的内部提供了一个FIFO队列

APlus 497

JAVA多线程基础篇-AQS(AbstractQueuedSynchronizer)

AQS(AbstractQueuedSynchronizer)抽象队列同步器,是一种用来构建锁和同步器的框架。在JAVA,AQS是其它同步组件的基础框架(ReentrantLock、Semaphore、CountDownLatch、ReentrantReadWriteLock、SynchronusQueue等),它是JUC并发包中的核心组件。它不仅解决了在实现同步器时涉及的大量细节问题(自定义标准同步状态、FIFO同步队列等),还充分考虑了伸缩性,降低了上下文开销、提高了吞吐量。

qq_33479841的博客 3976

深入浅出java并发编程(AbstractQueuedSynchronizer)(AQS)

深入浅出java并发编程(AbstractQueuedSynchronizer)(AQS)

CERTAINTY的博客 818
上一篇: java——Synchronized与Lock
下一篇: 算法基础——递归
夏子曦
夏子曦 优质创作者: 产品设计技术领域 优质创作者: 产品设计技术领域
博客等级 码龄15年 8289粉丝 427原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值