AbstractQueuedSynchronizer之AQS

2023-11-19

AbstractQueuedSynchronizer(AQS)

概述

AbstractQueuedSynchronizer(简称AQS)是Java中锁和同步器的基础框架,大多数的锁和同步器都是通过继承AQS来实现的。AQS提供了一个灵活的框架,使得开发者可以根据自己的需求来实现各种锁和同步器。本文将介绍AQS的基本原理和实现细节。

基本原理

AQS维护了一个state(状态)属性和一个等待队列。state用来表示同步状态,当state为0时表示锁没有被占用,当state不为0时表示锁已经被占用,state的含义和具体使用方法是由子类定义的。等待队列则用来存储那些请求锁或者同步器的线程。

当一个线程请求锁或同步器时,如果此时state为0,则表示当前线程可以获得锁或同步器,此时会将state设置为1,表示当前锁或同步器已经被占用了。如果此时state不为0,则表示此时锁或同步器正在被其他线程占用,此时当前线程会被加入到等待队列中,等待其他线程释放锁或同步器。

当其他线程释放了锁或同步器时,会唤醒等待队列中的一个线程,使其重新尝试获取锁或同步器。如果此时该线程又成功获取了锁或同步器,则该线程会从等待队列中移除。

实现细节

等待队列

AQS的等待队列是一个双向链表,每个节点表示一个等待线程(或者称为Node),Node继承自AbstractQueuedSynchronizer。下面是Node的定义:

static final class Node {
    // 共享模式
    static final Node SHARED = new Node();
    // 独占模式
    static final Node EXCLUSIVE = null;

    // waitStatus的值表示当前节点需要等待的状态
    static final int CANCELLED =  1;
    static final int SIGNAL    = -1;
    static final int CONDITION = -2;
    static final int PROPAGATE = -3;

    volatile int waitStatus;
    volatile Node prev;
    volatile Node next;
    volatile Thread thread;

    Node nextWaiter;

    final boolean isShared() {
        return nextWaiter == SHARED;
    }

    final Node predecessor() throws NullPointerException {
        Node p = prev;
        if (p == null)
            throw new NullPointerException();
        else
            return p;
    }

    Node() {
    }

    Node(Thread thread, Node mode) {     // Used by addWaiter
        this.nextWaiter = mode;
        this.thread = thread;
    }

    Node(Thread thread, int waitStatus) { // Used by Condition
        this.waitStatus = waitStatus;
        this.thread = thread;
    }
}

Node节点有以下属性:

  • waitStatus:表示节点的状态,可以是以下值:

    • CANCELLED:表示节点已经取消。
    • SIGNAL:表示在释放同步器或者锁时需要唤醒该节点。
    • CONDITION:表示节点在等待Condition时被阻塞。
    • PROPAGATE:表示共享模式下下一个节点需要唤醒。
  • prev:表示当前节点的前一个节点。

  • next:表示当前节点的后一个节点。

  • thread:表示当前节点所对应的线程。

  • nextWaiter:表示下一个等待节点。

等待队列的头节点是一个哑节点,不表示任何一个等待线程。当等待队列不为空时,队首节点表示正在占用同步器或者锁的线程,队列中剩下的节点表示正在等待获取同步器或者锁的线程。

等待队列的操作主要有以下几个:

  • enq(node):将一个节点加入等待队列的尾部。

  • addWaiter(mode):创建一个新的节点并加入到等待队列的尾部。mode表示该节点的模式,可以是独占模式或共享模式。

  • setHead(node):设置等待队列的头节点。

  • unparkSuccessor(node):唤醒等待队列中最近的一个还未被取消的节点。在独占模式下,需要唤醒的节点是当前节点的后继节点;在共享模式下,需要唤醒的节点是等待队列中第一个未被取消的节点。

state属性

AbstractQueuedSynchronizer中,state属性是一个volatile类型的整数,用来表示同步状态。子类可以通过修改state的值来实现自己的同步机制。

state为0时表示同步器或锁没有被占用,当state不为0时表示同步器或锁已经被占用。在独占模式下,state的值为1表示锁已经被占用,在共享模式下,state的值表示正在使用锁的线程数。

state的主要操作有以下几个:

  • getState():获取当前状态的值。

  • setState(newState):设置当前状态的值。

  • compareAndSetState(expect, update):原子性地将当前状态和expect比较,如果相等则将其设置为update,并返回true,否则返回false。

独占模式

AbstractQueuedSynchronizer中的独占模式是最常用的同步机制之一,代表了Java中的锁。

我们来看一下ReentrantLock是如何实现独占模式的。

ReentrantLock

ReentrantLock是一个可重入的互斥锁,它支持公平锁和非公平锁。ReentrantLock继承自AbstractQueuedSynchronizer,在ReentrantLock的构造方法中会调用AbstractQueuedSynchronizer的构造方法来初始化state属性和等待队列。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

AbstractQueuedSynchronizer之AQS 的相关文章

随机推荐

  • html文本元素

    文章目录 h p span pre code 实体字符 strong i em del s h h head 标题 一共有六级标题 hKaTeX parse error Expected got EOF at end of input 6
  • 【编译原理】 CS143 斯坦福大学公开课 第一周:简介

    youtube 1 1 Introduction to Compilers and interpreters 1 1 Introduction to Compilers and interpreters 编译器解释器介绍 两种主要的实现编程
  • three.js中聚光灯及其属性介绍

    一 聚光灯及其属性介绍 Three js中的聚光灯 SpotLight 是一种用于在场景中创建聚焦光照的光源类型 它有以下属性 color 聚光灯的颜色 intensity 聚光灯的强度 distance 聚光灯的有效距离 angle 聚光
  • [毕业设计]2023-2024年最新电子科学与技术专业毕设选题题目推荐汇总

    文章目录 1前言 2 如何选题 3 选题方向 3 1 嵌入式开发方向 3 2 物联网方向 3 3 人工智能方向 3 4 算法研究方向 3 5 学长作品展示 4 最后 1前言 近期不少学弟学妹询问学长关于电子科学与技术专业相关的毕设选题 学长
  • java如何检测连接池连接情况,如何检查是否使用了连接池

    I use HSQLDB EclipseLink Gemini on OSGI framework Felix In spite that I ve set pool in persistence xml I have serious su
  • 全网最全谷粒商城记录_01、简介-项目介绍(2022-07-06更新完成)

    声明 本教程不收取任何费用 欢迎转载 尊重作者劳动成果 不得用于商业用途 侵权必究 目录 分布式基础 全栈开发篇 分布式高级 微服务架构篇 高可用集群 架构师提升篇 希望大家 微服务架构图简单介绍 项目简介 1 项目背景 1 电商模式 1
  • JavaWeb学习笔记-part1

    互联网通信 什么是互联网通信 两台计算机通过网络实现文件共享行为 就是互联网通信 互联网通信中的角色划分 客户端 用于发送请求的计算机 服务端 用于接受请求 并满足请求的计算机 互联网通信模型 C S通信模型 client software
  • Handler机制与原理

    为什么会出现内存泄漏问题呢 分析 Handler使用是用来进行线程间通信的 所以新开启的线程是会持有Handler引用的 如果在Activity等中创建Handler 并且是非静态内部类的形式 就有可能造成内存泄漏 非静态内部类是会隐式持有
  • uniapp 开发微信小程序之新版隐私协议

    自从微信小程序官方更新隐私协议 用户必须同意之后 才能获取个人信息 这就导致在获取用户信息之前 需要有个隐私协议弹窗 大致如下图 微信小程序官方提供的API和 uniapp 开发的稍微有点区别 这里只记录 uniapp 开发的 如果需要微信
  • 高中学历的程序员,以包装的方式进入现在的公司,想跳槽咋办?

    网友自述 我在现在广州这家公司工作了两年 技术上有一定提升 但这两年我过得一直不是很快乐 因为我学历包装 所以我不敢跟同事交往太深 一直孤身一人 非常难受 可能这就是代价吧 现在我想换一个公司 我不想再用假身份了 但不知道用高中学历是否能够
  • Java对点、线、面生成栅格瓦片jpg,并渲染呈现

    Java对点 线 面生成栅格瓦片jpg 并渲染呈现 1 效果图 2 原理 2 1 面瓦片的生成 2 2 线瓦片的生成 2 3 多点瓦片的生成 3 源码 参考 这篇博客将介绍从前端HTML页面到后端预生成栅格瓦片jpg 并提供查询接口供前端h
  • Python文件操作

    1 with open E 信息 docx rb as f 2 read data f read 3 f closed rb 以二进制形式读取指定路径的文件 再以二进制形式写入指定路径 wb 1 with open E 信息 2 docx
  • Go Web编程实战(6)----反射

    目录 反射 反射的3大原则 接口类型变量 转换为 反射类型对象 反射类型对象 转换为 接口类型变量 反射类型对象 修改 值必 可写的 反射 与其他语言一样 Go语言的反射同样是指 计算机程序在运行时 可以访问 检测和修改它本身状态或行为的一
  • MAC 怎么终端怎么退出和进入Anaconda环境

    mac安装完anaconda 后 命令行窗口默认使用conda的 取消默认 用以下一行代码在命令行运行即可 重启终端 conda config set auto activate base false 将false改为true设置默认环境为
  • Codeforces 1475C. Ball in Berland(二元容斥)

    题目传送门 题意 一个班级有a个男生和b个女生 现在这个班级有k对男女愿意一起出席毕业典礼 这里注意k对男女中可能会有某个男生或女生出现在多个pair中 你从这k对中找出两对 使得这两对中的男生不相同 女生不相同 即一个男生或女生不可能在一
  • cuda 矩阵乘法,从最容易理解到算得最快(第二版源码-tile机制+共享内存)

    下面我们仅仅引入tiling方法 在共享内存中进行分块矩阵的乘法运算 先分析一下能够减少多少次对全局存储区的访问 当M N K 4096时 用第一版的代码 忽略cache的缓存时 需要从全局存储区读取2 4096 3 个float变量 为了
  • 法拉利虚拟学院2010 服务器,法拉利虚拟学院2010

    意大利著名好车品牌 法拉利 一直在世界上享受名誉 该游戏作品将带领玩家感悟法拉利的文化底蕴 游戏介绍 法拉利虚拟学院2010 包括了2010款法拉利F1赛车F10 以及三条通过镭射扫描技术绘制的高精度赛道 Fiorano Mugello N
  • spring boot 简介以及作用

    我们都知道spring是一个功能非常强大的框架 但是它也存在非常不好的弱点 也是对于我们普通的程序员的致命的弱点 就是它的配置文件太多了 而 在开发界一直有一句话 就是约定大于配置 这样一句话 就是说系统 类库 框架应该假定合理的默认值 而
  • JsonObject对象和jsonArrsy数组的获取JDK1.8,添加到表中

    1 基础数据结构 一个合同号对应多个批号 一个批号对应多个车辆 arrivalReport contractContent contractNumber 2021 11 17合同号 orderNumber 2021 11 17 0032订单
  • AbstractQueuedSynchronizer之AQS

    文章目录 AbstractQueuedSynchronizer AQS 概述 基本原理 实现细节 等待队列 state属性 独占模式 ReentrantLock AbstractQueuedSynchronizer AQS 概述 Abstr