首页 > 其他分享 >AQS 原理

AQS 原理

时间:2024-03-22 09:23:03浏览次数:29  
标签:同步 AQS 队列 int 线程 原理 节点

AQS(AbstractQueuedSynchronizer)是 Java 中用于构建锁和同步器的框架,它是并发包中很多同步类的基础。AQS 提供了一种基于 FIFO 等待队列的同步器实现,通过内置的队列和状态管理机制,可以实现各种同步器,如 ReentrantLock、CountDownLatch、Semaphore 等。

AQS 的核心思想是使用一个整型的状态变量来表示同步状态,同时维护一个 FIFO 的等待队列来管理获取锁失败的线程。AQS 包含两种操作:独占操作(acquire)和共享操作(release)。独占操作是指只有一个线程可以获取同步状态,而共享操作是指多个线程可以同时获取同步状态。

AQS 的主要方法包括:

  1. acquire(int arg):获取同步状态,如果获取成功返回 true,否则阻塞等待。
  2. release(int arg):释放同步状态,唤醒等待队列中的线程。
  3. tryAcquire(int arg):尝试获取同步状态,获取成功返回 true,否则返回 false。
  4. tryRelease(int arg):尝试释放同步状态,释放成功返回 true,否则返回 false。

AQS 的内部实现主要涉及到以下几个重要的方法:

  1. acquireQueued(Node node, int arg):将当前线程以节点的形式加入到等待队列中,并自旋等待获取同步状态。
  2. tryAcquire(int arg):尝试获取同步状态,如果成功返回 true,否则返回 false。
  3. release(int arg):释放同步状态,唤醒等待队列中的头节点(即等待时间最长的线程)。
  4. tryRelease(int arg):尝试释放同步状态,如果成功返回 true,否则返回 false。
  5. addWaiter(Node mode):将当前线程以节点的形式加入到等待队列中。

AQS 的设计使得它可以支持独占锁(Exclusive Lock)和共享锁(Share Lock),并且可以方便地构建更复杂的同步器。通过继承 AQS 并实现 acquire 和 release 方法,开发者可以定制自己的同步器,实现更灵活和高效的并发控制。AQS 的实现为 Java 中锁和同步器的高效、灵活提供了基础。

什么是 AQS定义:AbstarctQueuedSynchronizer 简称 AQS,是一个用于构建锁和同步容器的框架。

事实上 concurrent 包内许多类都是基于 AQS 构建的,例如 ReentrantLock,ReentrantReadWriteLock,FutureTask 等。AQS 解决了在实现同步容器时大量的细节问题。

 

AQS 使用一个 FIFO 队列表示排队等待锁的线程,队列头结点称作 “哨兵节点” 或者 “哑结点”,它不与任何线程关联。其他的节点与等待线程关联,每个阶段维护一个等待状态 waitStatus。

AQS 提供的两种功能

从使用层面来说,AQS 的锁功能分为两种:独占锁和共享锁。

独占锁:每次只能有一个线程持有锁,比如前面给大家演示的 ReentrantLock 就是以独占方式实现的互斥锁;
共享锁:允许多个线程同时获取锁,并发访问共享资源,比如 ReentrantReadWriteLock。

4. AQS 的内部实现

AQS 的实现依赖内部的同步队列,也就是 FIFO 的双向队列,如果当前线程竞争锁失败,那么 AQS 会把当前线程以及等待状态信息构造成一个 Node 加入到同步队列中,同时再阻塞该线程。当获取锁的线程释放锁以后,会从队列中唤醒一个阻塞的节点 (线程)。

如下图所示,一个节点表示一个线程,它保存着线程的引用(thread)、状态(waitStatus)、前驱节点(prev)、后继节点(next),其实就是个双端双向链表,其数据结构如下:

 

Tips:AQS 队列内部维护的是一个 FIFO 的双向链表,这种结构的特点是每个数据结构都有两个指针,分别指向直接的后继节点和直接前驱节点。所以双向链表可以从任意一个节点开始,很方便的访问前驱和后继。每个 Node 其实是由线程封装,当线程争抢锁失败后会封装成 Node 加入到 ASQ 队列中去。

添加线程对于 AQS 队列的变化

当出现锁竞争以及释放锁的时候,AQS 同步队列中的节点会发生变化,首先看一下添加线程的场景。

 

这里会涉及到两个变化:

  • 队列操作的变化:新的线程封装成 Node 节点追加到同步队列中,设置 prev 节点以及修改当前节点的前置节点的 next 节点指向自己;
  • tail 指向变化:通过同步器将 tail 重新指向新的尾部节点。

6. 释放锁移除节点对于 AQS 队列的变化

第一个 head 节点表示获取锁成功的节点,当头结点在释放同步状态时,会唤醒后继节点,如果后继节点获得锁成功,会把自己设置为头结点,节点的变化过程如下:

 

这个过程也是涉及到两个变化:

head 节点指向:修改 head 节点指向下一个获得锁的节点;
新的获得锁的节点:如图所示,第二个节点被 head 指向了,此时将 prev 的指针指向 null,因为它自己本身就是第一个首节点,所以 pre 指向 null。

 

标签:同步,AQS,队列,int,线程,原理,节点
From: https://www.cnblogs.com/RedOrange/p/18057023

相关文章

  • Kubernetes之Pod基本原理与实践
    一、Pod的定义与基本用法1.Pod是什么Pod是可以在Kubernetes中创建和管理的、最小的可部署的计算单元。Pod不是进程,而是容器运行的环境。Pod所建模的是特定于应用的“逻辑主机”,其中包含一个或多个应用容器。当Pod包含多个应用容器时,这些容器的应用之间应该是......
  • 408计算机组成原理知识点——第一章 计算机系统概述
    文章目录计算机发展历程计算机系统层次结构早期冯诺依曼机现代计算机的结构各个硬件的工作原理主存储器的基本组成运算器的基本组成控制器的基本组成计算机的工作过程计算机软件系统软件和应用软件三种级别的语言软件和硬件的逻辑功能等价性计算机系统的层次结构计算机......
  • 【面试精讲】JVM 的内存布局和运行原理(附代码)
    【面试精讲】JVM的内存布局和运行原理(附代码)目录一、JVM内存布局1、堆(Heap)2、方法区(MethodArea)3、程序计数器(ProgramCounterRegister)4、虚拟机栈(VMStack)5、本地方法栈(NativeMethodStack)二、JVM运行原理1、类加载机制2、类加载机制详解2.1、 加载阶段2.2、......
  • Java 8 内存管理原理解析及内存故障排查实践
    作者:vivo互联网服务器团队- ZengZhibin介绍Java8虚拟机的内存区域划分、内存垃圾回收工作原理解析、虚拟机内存分配配置,介绍各垃圾收集器优缺点及场景应用、实践内存故障场景排查诊断,方便读者面临内存故障时有一个明确的思路和方向。一、背景Java是一种流行的编程语言,可......
  • 探索半导体产业:从原理到应用
    半导体产业作为当今科技领域的重要支柱之一,其影响已经渗透到了我们日常生活的方方面面。从电子设备到通信系统,从医疗器械到智能家居,无处不在的半导体技术正在改变着我们的世界。本文将深入探讨半导体产业的各个方面,从其基本原理到最新的应用趋势。 1.半导体的基本原理半导体......
  • 深度解读UUID:结构、原理以及生成机制
    What是UUIDUUID(UniversallyUniqueIDentifier)通用唯一识别码,也称为GUID(GloballyUniqueIDentifier)全球唯一标识符。UUID是一个长度为128位的标志符,能够在时间和空间上确保其唯一性。UUID最初应用于Apollo网络计算系统,随后在OpenSoftwareFoundation(OSF)的分布式......
  • golang 中 channel cap设为1原理 | 有无缓冲的channel
    在golang中,如果涉及消息传递或者是并发控制等,我们常常用到channel,channel的具体原理这里不讨论,今天主要看看有无缓冲以及缓冲值的设计。无缓冲的channel联系channel的数据结构mchan可知,就没得buf,但sendqrecvq这些肯定都是有的,所以在无缓冲的channel中,如果写者写入ch......
  • golang 多返回值的实现原理-转载
    之前一次面试时,面试官问到你知道golang的多返回值的实现吗,一脸懵逼,平时主要注重项目应用开发,对这块确实没关注,答得不好,各位大佬,以后建议也加强下基础哦。今天看看golang中多返回值的实现。可以简单认为c中多返回值的实现,其实就是通过寄存器将返回参数以指针形式传入传入参......
  • C++ <atomic>汇编语言实现原理
    C++<atomic>汇编语言实现原理问题我们先看一下这段代码:/**badcnt.c-Animproperlysynchronizedcounterprogram*//*$beginbadcnt*//*WARNING:Thiscodeisbuggy!*/#include"csapp.h"void*thread(void*vargp);/*Threadroutineprototype*//*......
  • socket 技术是干什么的?底层原理是什么?
    Socket技术是一种通信机制,用于实现不同计算机之间的网络通信和同一计算机内不同进程之间的进程间通信。它是一种抽象层,使得不同操作系统和编程语言的程序能够在网络上相互通信。底层原理方面,Socket技术基于网络协议栈和操作系统提供的网络编程接口。当程序使用Socket技术......