AQS 概述

AQS(队列同步器,AbstractQueuedSynchronizer),是用来构建锁或其他同步组件的核心基础框架(比如 ReentrantLock、ReentrantReadWriteLock、Semaphore、CountDownLatch)

AQS的底层结构是:一个整型变量state表示同步状态,一个内置的FIFO队列(同步队列)来实现资源获取线程的同步等待排队,若干个FIFO队列(条件等待队列)来完成持有资源线程的条件等待排队。同步队列如下:

AQS的使用方式

同步器的设计是基于模板方法模式的,其使用方式是继承,子类通过继承同步器并重写指定的模板方法,模板方法分为3类:独占式获取与释放同步状态、共享式获取与释放同步状态、查询队列中的等待线程。在重写过程中可以使用同步器提供的3个方法来管理同步状态state:getState()、setState()和compareAndSetState(),因为它们能够保证state的改变是并发安全的。

当实现一个自定义同步组件时,推荐在内部聚合/组合一个同步器的实现类,该自定义同步组件将通过调用同步器提供的模板方法来实现自己的同步语义。为什么不直接使用同步器呢?因为同步器自身没有实现任何同步接口,它仅仅是定义了若干管理同步状态的方法,这样有利于实现各种类型的同步组件

同步器与锁的关系

同步器是实现锁的关键,在锁的实现中聚合/组合了一个同步器,利用该同步器实现了锁的语义。

可以这样理解二者之间的关系:锁是面向使用者的,它定义了使用者与锁的交互接口,隐藏了实现细节;而同步器面向的是锁的实现者,它简化了锁的实现方式,包括屏蔽同步状态管理、线程的排队、等待与唤醒等底层操作。锁和同步器很好地隔离了使用者和实现者所需关注的领域。

AQS:获取与释放同步状态

1.独占式获取同步状态

查看源码 AbstractQueuedSynchronizer.acquire(..)

public final void acquire(int arg) {
//tryAcquire(..) 尝试获取同步状态,由子类重写,最经典的实现是互斥锁:state=0(锁自由),state>0(锁被占用)
//acquireQueued(..) 进入同步队列,阻塞等待获取锁
if (!tryAcquire(arg) &&
acquireQueued(addWaiter(Node.EXCLUSIVE), arg))
selfInterrupt();
}

由于acquire(..)方法不响应中断,因此AQS也提供了响应中断、超时等待的方法:acquireInterruptibly(..)、tryAcquireNanos(..)

2.独占式释放同步状态

查看源码 AbstractQueuedSynchronizer.release(..)

public final boolean release(int arg) {
//tryAcquire(..) 尝试释放同步状态,由子类重写
if (tryRelease(arg)) {
Node h = head;
//unparkSuccessor(..) 唤醒被挂起的Node(线程)
if (h != null && h.waitStatus != 0)
unparkSuccessor(h);
return true;
}
return false;
}

3.共享式获取同步状态

查看源码 AbstractQueuedSynchronizer.acquireShared(..)

public final void acquireShared(int arg) {
//tryAcquireShared(..) 尝试获取同步状态,由子类重写,最经典的实现是信号量:state>0(锁很多),state<0(锁不足)
//doAcquireShared(..) 进入同步队列,阻塞等待获取锁
if (tryAcquireShared(arg) < 0)
doAcquireShared(arg);
}

由于acquireShared(..)方法不响应中断,因此AQS也提供了响应中断、超时等待的方法:acquireSharedInterruptibly(..)、tryAcquireSharedNanos(..)

4.共享式释放同步状态

查看源码 AbstractQueuedSynchronizer.

public final boolean releaseShared(int arg) {
//tryReleaseShared(..) 尝试释放同步状态,由子类重写
if (tryReleaseShared(arg)) {
//doReleaseShared(..) 唤醒被挂起的Node(线程)
doReleaseShared();
return true;
}
return false;
}

参考文章:

Java AQS 概述的更多相关文章

  1. Java AQS学习

    参考原文: Java并发之AQS详解 <Java并发编程的艺术> AQS 概述 AQS简介 AQS(AbstractQueuedSynchronizer)就是一个抽象的队列同步器,它是用来 ...

  2. Java Annotation概述

    @(Java)[Annotation|Java] Java Annotation概述 用途 编译器的相关信息,如用于检测错误和一些警告 编译时和部署时的处理,如一些软件用于自动生成代码之类的 运行时处 ...

  3. 《java集合概述》

    JAVA集合概述: Collection: |---List有序的:通过索引就可以精确的操作集合中的元素.元素是可以重复的. List提供了增删改查的动作. 增加add(element) add(in ...

  4. Java的概述以及语法

    Java的语法分为标示符和数据类型 Java的概述: 一些手打的: long l = 12345; //隐式转换 int a = (int)121234567L; //强制转换 float f =12 ...

  5. Java集合概述、Set集合(HashSet类、LinkedHashSet类、TreeSet类、EnumSet类)

    Java集合概述.Set集合(HashSet类.LinkedHashSet类.TreeSet类.EnumSet类) 1.Java集合概述1)数组可以保存多个对象,但数组长度不可变,一旦在初始化数组时指 ...

  6. Java笔记:Java集合概述和Set集合

    本文主要是Java集合的概述和Set集合 1.Java集合概述 1)数组可以保存多个对象,但数组长度不可变,一旦在初始化数组时指定了数组长度,这个数组长度就是不可变的,如果需要保存数量变化的数据,数组 ...

  7. Java NIO学习笔记一 Java NIO概述

    Java NIO概述 Java NIO(新的IO)是Java的替代IO API(来自Java 1.4),这意味着替代标准的 java IO和java Networking API.Java NIO提供 ...

  8. java基础---java语言概述

    一.计算机编程的两种范型 1.面向过程的模型---具有线性执行特点,认为是代码作用于数据. 2.面向对象的模型---围绕它的数据(即对象)和为这个数据定义的接口来组织程序:实际上是用数据控制代码的访问 ...

  9. Java核心技术(Java白皮书)卷Ⅰ 第一章 Java程序设计概述

    第1章 Java程序设计概述1.1 Java程序设计平台 具有令人赏心悦目的语法和易于理解的语言,与其他许多优秀语言一样,Java满足这些要求. 可移植性 垃圾收集 提供大型的库  如果想要有奇特的绘 ...

随机推荐

  1. 小程序wx:for循环列表数量的限制

    数据有100条,我们只要页面显示一部分,就要通过index来限制.index<3,就是显示序列0,1,2这三条数据.具体写法: <block wx:for='{{list}}' wx:ke ...

  2. 《JavaScript DOM编程艺术》学习笔记(二)

    终于开始接着写我的读书笔记了. 17.DOM有insertBefore方法,但并没有提供insertAfter()方法.不过可利用已有的DOM方法和属性编写此函数: function insertAf ...

  3. SSIS - 5.优先约束

      一.优先约束和执行逻辑 任务和容器是SSIS中的可执行文件,一个优先约束连接着两个可执行文件:优先的可执行文件和约束的可执行文件,如下图. 它的执行逻辑如下图: 1)先执行优先可执行文件 2)判断 ...

  4. Tomcat线程池配置

    简介  线程池作为提高程序处理数据能力的一种方案,应用非常广泛.大量的服务器都或多或少的使用到了线程池技术,不管是用Java还是C++实现,线程池都有如下的特点:线程池一般有三个重要参数: 最大线程数 ...

  5. RabbitMQ进程结构分析与性能调优

    RabbitMQ是一个流行的开源消息队列系统,是AMQP(高级消息队列协议)标准的实现,由以高性能.健壮.可伸缩性出名的Erlang语言开发,并继承了这些优点.业界有较多项目使用RabbitMQ,包括 ...

  6. [Swift]LeetCode982. 按位与为零的三元组 | Triples with Bitwise AND Equal To Zero

    Given an array of integers A, find the number of triples of indices (i, j, k) such that: 0 <= i & ...

  7. Spring设计模式_策略模式/其他

    策略模式特性 1.执行最终结果一样 2.执行过程和执行逻辑不一样 3.使用同一接口 达到目的就可以了 Git地址 https://github.com/wujiachengSH/WjcStrategy ...

  8. 【从零开始自制CPU之学习篇02】555定时器

    555定时器是一种集成电路芯片,常被用于定时器.脉冲产生器和震荡电路.在CPU制作中作为pc(程序计数器)的主要组成部分.以下是我购买的NE555实拍图: NE555的针脚示意图: 555定时器各针脚 ...

  9. Spring Boot Security

    如图,是一种通用的用户权限模型.一般情况下会有5张表,分别是:用户表,角色表,权限表,用户角色关系表,角色权限对应表. 一般,资源分配时是基于角色的(即,资源访问权限赋给角色,用户通过角色进而拥有权限 ...

  10. redis 系列10 字符串对象

    一. 字符串对象编码 Redis中字符串可以存储3种类型,分别是字节串(byte string).整数.浮点数.在上章节中讲到字符串对象的编码可以是int, raw,embstr. 如果一个字符串对象 ...