学Java线程,你不知道什么是AQS?一文带你进入Java多线程同步的灵魂-AbstractQueuedSynchronizer

这篇具有很好参考价值的文章主要介绍了学Java线程,你不知道什么是AQS?一文带你进入Java多线程同步的灵魂-AbstractQueuedSynchronizer。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

关于作者:CSDN内容合伙人、技术专家, 从零开始做日活千万级APP。
专注于分享各领域原创系列文章 ,擅长java后端、移动开发、人工智能等,希望大家多多支持。

一、导读

我们继续总结学习Java基础知识,温故知新。

1.1 CLH锁

CLH(Craig, Landin, and Hagersten locks)是一种自旋锁,能确保无饥饿性,提供先来先服务的公平性。
CLH锁是一种基于链表的可扩展、高性能、公平的自旋锁,申请线程只在本地变量上自旋,它不断轮询前驱的状态,如果发现前驱释放了锁就结束自旋。
学Java线程,你不知道什么是AQS?一文带你进入Java多线程同步的灵魂-AbstractQueuedSynchronizer,java学习之路,开发语言,面试,android,线程,java

二、概览

AbstractQueuedSynchronizer 是抽象队列同步器,是一种用来构建锁和同步器的框架

AQS主要做了三件事情

  • 同步状态的管理
  • 线程的阻塞和唤醒
  • 同步队列的维护

AQS 定义了同步器的基本操作,如获取、释放和状态管理,并提供了一个等待队列来管理等待资源的线程,解决了在实现同步器时涉及的大量细节问题,例如自定义标准同步状态、FIFO 同步队列。

基于 AQS 来构建同步器可以带来很多好处。它不仅能够极大地减少实现工作,而且也不必处理在多个位置上发生的竞争问题。

三、使用场景

AQS 是一个相对底层的同步器框架,对于一些常见的同步需求,Java 并发库已经提供了许多高级封装,如 ReentrantLock、ReadWriteLock、Semaphore 等,这些高级封装已经为我们提供了更简单易用的接口和功能。因此,在应用开发中,直接使用 AQS 的场景相对较少,更多的是通过使用它的子类来实现具体的同步机制。

常用的同步器有:

  1. 独占锁(如 ReentrantLock):AQS 提供了 acquire(int arg) 和 release(int arg) 等方法,开发人员可以继承 AQS 并实现自定义的同步器来实现独占锁。通过控制同步状态(通过 getState() 和 setState(int newState) 方法),以及管理等待线程(通过等待队列),AQS 可以提供可重入锁、公平锁等不同类型的独占锁。

  2. 共享锁(如 ReadWriteLock):AQS 也可以用于实现共享锁机制,例如 ReentrantReadWriteLock。通过 acquireShared(int arg) 和 releaseShared(int arg) 等方法,开发人员可以自定义实现共享锁的逻辑。AQS 提供了对多个读线程和写线程的管理和协调,以及对读线程的优化。

  3. 实现其他同步工具:AQS 的框架还可以用于实现其他类似的同步工具,如信号量(Semaphore)、倒计时器(CountDownLatch)、循环屏障(CyclicBarrier)等。

通过继承 AQS 并自定义同步器的行为,可以实现不同的同步机制。

3.1 AQS 对资源的共享方式

  1. Exclusive(独占):只有一个线程能执行,如ReentrantLock。

    资源锁可分为公平锁和非公平锁:

  • 公平锁:按照线程在队列中的排队顺序(FIFO),先到者先拿到锁。
    学Java线程,你不知道什么是AQS?一文带你进入Java多线程同步的灵魂-AbstractQueuedSynchronizer,java学习之路,开发语言,面试,android,线程,java

  • 非公平锁:当线程要获取锁时,无视队列顺序直接去抢锁,谁抢到就是谁的(被唤醒的线程和新来的线程重新竞争锁)。
    学Java线程,你不知道什么是AQS?一文带你进入Java多线程同步的灵魂-AbstractQueuedSynchronizer,java学习之路,开发语言,面试,android,线程,java

  1. Share(共享):多个线程可同时执行,如Semaphore/CountDownLatch。Semaphore、CountDownLatCh、 CyclicBarrier、ReadWriteLock 我们都会在后面讲到。

四、原理

AQS大致流程如下:
1、当某一线程获取锁后,将state值+1,并记录下当前持有锁的线程。
2、再有线程来获取锁时,判断这个线程与持有锁的线程是否是同一个线程,如果是,将state值再+1,如果不是,阻塞线程(调用 LockSupport.park(this)挂起线程)。
3、当线程释放锁时,将state值-1。
4、当state值减为0时,表示当前线程彻底释放了锁。
5、然后将记录当前持有锁的线程的那个字段设置为null,并唤醒其他线程,使其重新竞争锁

4.1 原理

AQS使用一个 Volatile的 int类型的成员 state 变量来表示同步状态,通过内置的FIFO队列来完成资源获取的排队工作(双向链表,多线程争用资源被阻塞时会进入此队列),然后通过CAS完成对State值的修改。

其并发控制的核心是锁的获取与释放,锁的实现方式有很多种,AQS采用的是一种改进的CLH锁。


    当state=0表示释放了锁,当state>0表示获得锁
    /**
     * The synchronization state.
     */
    private volatile int state;
    
    
	封装一个Node,包含前节点,后节点,组成一个双向队列。
	private transient volatile Node head;

	private transient volatile Node tail;

学Java线程,你不知道什么是AQS?一文带你进入Java多线程同步的灵魂-AbstractQueuedSynchronizer,java学习之路,开发语言,面试,android,线程,java

CLH(Craig,Landin,and Hagersten)队列是一个虚拟的双向队列(虚拟的双向队列即不存在队列实例,仅存在结点之间的关联关系)。

AQS是将每条请求共享资源的线程封装成一个CLH锁队列(FIFO同步队列)的一个结点(Node)来实现锁的分配。

如果线程获取当前同步状态失败,AQS会将当前线程的信息封装成一个Node节点,加入同步队列中,并且阻塞该线程,当同步状态释放,则会将队列中的线程唤醒,重新尝试获取同步状态。

我们看下node源码:

static final class Node {
    /** 共享节点 */
    static final Node SHARED = new Node();
    /** 独占节点 */
    static final Node EXCLUSIVE = null;

    当前节点在队列中的状态
    volatile int waitStatus;

    前驱指针
    volatile Node prev;

    后继指针
    volatile Node next;

    表示处于该节点的线程
    volatile Thread thread;

    指向下一个处于CONDITION状态的节点
    Node nextWaiter;
}

五、 推荐阅读

【Java基础】原子性、可见性、有序性

【Java基础】java可见性之 Happens-before

【Java基础】java-android面试Synchronized

【Java基础】java-android面试-线程状态

【Java基础】线程相关

【Java基础】java 异常

【Java基础】java 反射

【Java基础】java 泛型

【Java基础】java注解

【Java基础】java动态代理

【Java基础】Java SPI

【Java基础】Java SPI 二 之 Java APT

【Java基础】 jvm 堆、栈、方法区 & java 内存模型

【Java基础】volatile关键字

【Java基础】线程同步类 CountDownLatch

【Java基础】CAS (Compare And Swap) 操作文章来源地址https://www.toymoban.com/news/detail-559684.html

到了这里,关于学Java线程,你不知道什么是AQS?一文带你进入Java多线程同步的灵魂-AbstractQueuedSynchronizer的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 深入浅出Java多线程(十一):AQS

    大家好,我是你们的老伙计秀才!今天带来的是[深入浅出Java多线程]系列的第十一篇内容:AQS( AbstractQueuedSynchronizer )。大家觉得有用请点赞,喜欢请关注!秀才在此谢过大家了!!! 在现代多核CPU环境中,多线程编程已成为提升系统性能和并发处理能力的关键手段。然而

    2024年03月12日
    浏览(52)
  • 不知道该学那一个语言?一文带你了解三门语言

    名字:阿玥的小东东 学习:Python。正在学习c++ 主页:阿玥的小东东 目录 粉丝留言,回答问题 1.首先,初步了解 

    2024年02月21日
    浏览(48)
  • AIGC领域的多模态深度学习你知道多少?一文带你Get

    Look!👀我们的大模型商业化落地产品 📖更多AI资讯请👉🏾关注 Free三天集训营助教在线为您火热答疑👩🏼‍🏫 什么是多模态深度学习? 多模态深度学习(英文名:Multimodal Deep Learning)是人工智能(AI)的一个子领域, 其重点是开发能够同时处理和学习多种类型数据的模型。这些

    2024年01月20日
    浏览(68)
  • 听说你还不知道什么是 python?带你深入理解什么是 python

    各位朋友们,大家好。在之后的时间里,我将陆续为大家分享我在python学习过程中学习到的知识点,如果你也对python感兴趣的话,欢迎大家来订阅我的python专栏哦,如果大家觉得博主的文章写得不错的话,记得给博主点个赞支持一下哦! Python是一种面向对象、解释型的高级编

    2024年02月11日
    浏览(34)
  • 一文带你了解什么是数学建模

    ​ 数学建模,就是根据实际问题来建立数学模型,对数学模型来进行求解,然后根据结果去解决实际问题。用通俗易懂的话讲就是1到3个人组队要从3-4个“应用题”中选出一个题之后独立在指导老师的指导下建立一个数学模型来解这道题最后再将数学模型、解题思路、方法过

    2024年02月04日
    浏览(48)
  • 【Docker】什么是Docker?一文带你了解

    Docker提供了标准化交付的创新途径 ,使开发、测试、部署过程通过流水线工具可见可控可信。 所以总结起来就是:Docker解决了运行环境和配置问题,构建过程标准化,也就方便做持续集成和持续交付。 目录 前言 1、Docker的介绍: 2、Docker的由来: 3、Docker的发展史: 4、Doc

    2024年02月12日
    浏览(43)
  • 你不知道的 ES2023

    6 月 27 日 ECMA 大会批准了 ECMAScript 2023 (es14)规范,意味着新的一些语法将正式成为标准。下面来看看 ECMAScript 2023 有哪些值得我们关注的新特性。 具体相关提案原文详情可以跳转:已完成提案 •从后往前查找数组 •Hashbang 语法 •Symbol 类型作为 WeakMap 类型的键 •不改变原数组

    2024年02月15日
    浏览(61)
  • 什么是VHDL?一文带你了解VHDL语言

    基于FPGA的SOC在嵌入式系统应用越来越广了,比较流行的硬件描述语言有两种Verilog HDL/VHDL,均为IEEE标准。VHDL如果有C语言基础的话就会比较容易上手。而VHDL语言则需要Ada编程基础。另外VHDL语言具有大量成熟的模块,从某种角度说VHDL更具生命力。 VHDL 的历史 VHDL 的 英 文 全 名

    2024年02月05日
    浏览(48)
  • HTTPS介绍:一文带你了解什么是HTTPS

    随着互联网的快速发展,网络安全问题日益凸显。在互联网上传输敏感信息、进行在线交易和共享个人数据时,确保数据的安全性和隐私保护成为了至关重要的任务。为了解决这些问题, HTTPS(超文本传输安全协议) 应运而生,成为了保护网络通信的重要一环。 HTTPS是HTTP协

    2024年02月09日
    浏览(48)
  • 一文带你全面了解什么是自动化测试?

    目录 简介 自动化测试概述 自动化测试目标 自动化测试流程 1. 测试计划和设计 2. 测试脚本开发 3. 测试执行和管理 4. 测试维护和优化 自动化测试最佳实践 自动化测试工具和框架 结论 软件测试是软件开发过程中一个必不可少的环节。传统的软件测试方式通常是手动测试,即

    2024年02月16日
    浏览(44)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包