Java AQS 概述
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 概述的更多相关文章
- Java AQS学习
参考原文: Java并发之AQS详解 <Java并发编程的艺术> AQS 概述 AQS简介 AQS(AbstractQueuedSynchronizer)就是一个抽象的队列同步器,它是用来 ...
- Java Annotation概述
@(Java)[Annotation|Java] Java Annotation概述 用途 编译器的相关信息,如用于检测错误和一些警告 编译时和部署时的处理,如一些软件用于自动生成代码之类的 运行时处 ...
- 《java集合概述》
JAVA集合概述: Collection: |---List有序的:通过索引就可以精确的操作集合中的元素.元素是可以重复的. List提供了增删改查的动作. 增加add(element) add(in ...
- Java的概述以及语法
Java的语法分为标示符和数据类型 Java的概述: 一些手打的: long l = 12345; //隐式转换 int a = (int)121234567L; //强制转换 float f =12 ...
- Java集合概述、Set集合(HashSet类、LinkedHashSet类、TreeSet类、EnumSet类)
Java集合概述.Set集合(HashSet类.LinkedHashSet类.TreeSet类.EnumSet类) 1.Java集合概述1)数组可以保存多个对象,但数组长度不可变,一旦在初始化数组时指 ...
- Java笔记:Java集合概述和Set集合
本文主要是Java集合的概述和Set集合 1.Java集合概述 1)数组可以保存多个对象,但数组长度不可变,一旦在初始化数组时指定了数组长度,这个数组长度就是不可变的,如果需要保存数量变化的数据,数组 ...
- Java NIO学习笔记一 Java NIO概述
Java NIO概述 Java NIO(新的IO)是Java的替代IO API(来自Java 1.4),这意味着替代标准的 java IO和java Networking API.Java NIO提供 ...
- java基础---java语言概述
一.计算机编程的两种范型 1.面向过程的模型---具有线性执行特点,认为是代码作用于数据. 2.面向对象的模型---围绕它的数据(即对象)和为这个数据定义的接口来组织程序:实际上是用数据控制代码的访问 ...
- Java核心技术(Java白皮书)卷Ⅰ 第一章 Java程序设计概述
第1章 Java程序设计概述1.1 Java程序设计平台 具有令人赏心悦目的语法和易于理解的语言,与其他许多优秀语言一样,Java满足这些要求. 可移植性 垃圾收集 提供大型的库 如果想要有奇特的绘 ...
随机推荐
- Java基础-对象与类
面向对象程序设计概述 面向对象的程序设计(简称OOP)时当今主流的程序设计范型,已经取代了"结构化"过程化程序设计开发技术,Java是完全面向对象的. 类 类设计构造对象的模板或蓝 ...
- sqlmap Windows 安装教程
第一步:下载 python :https://www.python.org/downloads/ (这里有python各种版本,但是一般建议安装3和2.7) sqlmap:https://git ...
- 解决TCPDF中文乱码,PHP
/* **主要是这个单词控制 stsongstdlight **/ $this->SetFont('stsongstdlight', 'B', 10);
- DOS命令(一)
1. echo 输出内容,用来输出文字. [例如:echo hello] 2. titile 标题,用来修改标题. 3. color 背景色前景色,用来设置背景色和前景色 0 = 黑色 8 = 灰色 ...
- VBS列出windows更新列表
Set objSession = CreateObject("Microsoft.Update.Session") Set objSearcher = objSession.Cre ...
- python Cookie Session 相关用法
Cookie一.前言1.http协议是无状态的. 无状态的意思是每次请求都是独立的,它的执行情况和结果与前面的请求和之后的请求都无直接关系,它不会受前面的请求响 应情况直接影响,也不会直接影响后面的请 ...
- js操作DOM对象
js操作DOM对象 (Document Object Model)文档对象模型 nodeType返回值 1:元素节点 2:属性节点 3:文本节点 8:注释节点 9: 文档节点 nodeName 节点 ...
- 对某菠菜网站的一次渗透测试 heatlevel
前言 无意间发现一个thinkphp的菠菜站,最近tp不是刚好有个漏洞吗?然后就顺手测试了一下,但过程并不太顺利,不过最后还是拿下了,所以特发此文分享下思路. 0x00 一键getshell? 简单看 ...
- [Swift]LeetCode406. 根据身高重建队列 | Queue Reconstruction by Height
Suppose you have a random list of people standing in a queue. Each person is described by a pair of ...
- [Swift]LeetCode442. 数组中重复的数据 | Find All Duplicates in an Array
Given an array of integers, 1 ≤ a[i] ≤ n (n = size of array), some elements appear twice and others ...