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满足这些要求. 可移植性 垃圾收集 提供大型的库 如果想要有奇特的绘 ...
随机推荐
- python面向对象的知识梳理
面向对象(Object Oriented Programming) 三个基本特征: 1.封装:包含两个概念,对象将变量(状态)和方法(用来改变状态或执行涉及状态的计算)集中在一个地方—即对象本身. 通 ...
- JS加密对应的c#解码
escape不编码字符有69个:*,+,-,.,/,@,_,0-9,a-z,A-Z encodeURI不编码字符有82个:!,#,$,&,',(,),*,+,,,-,.,/,:,;,=,? ...
- Rewrite JSON project with Fetch
上传 JSON 数据 使用fetch()来发布json编码的数据. var url = 'https://example.com/profile'; var data = {username: 'ex ...
- windows运维如何批量远程桌面
作用:windows下批量管理远程桌面, http://www.appmazing.com/ 官方站点 http://www.appmazing.com/files/RDO_Setup.exe wi ...
- 【RL-TCPnet网络教程】第17章 RL-TCPnet之UDP通信
第17章 RL-TCPnet之UDP通信 本章节为大家讲解RL-TCPnet的UDP通信实现,学习本章节前,务必要优先学习第16章UDP用户数据报协议基础知识.有了这些基础知识之后,再搞本章 ...
- 从SQL注入到内网漫游
前言 在一次渗透实战中,发现了一个注入点,最后成功的漫游了内网. 正文 在渗透中遇到一个站点,顺手测试了一下,在搜索框随便输入了一个字符加个单引号直接报错了,差不多可以确认这里存在注入了.一般这种站安 ...
- [Swift]LeetCode397. 整数替换 | Integer Replacement
Given a positive integer n and you can do operations as follow: If n is even, replace n with n/2. If ...
- [Swift]LeetCode700. 二叉搜索树中的搜索 | Search in a Binary Search Tree
Given the root node of a binary search tree (BST) and a value. You need to find the node in the BST ...
- PostgreSQL基础知识分享
1.架构 PostgreSQL是一个关系数据库,采用c/s架构.一个PostgreSQL会话包括: 服务端进程——postgres:用于管理数据库文件,并接受来自客户端的数据库连接, 同时代替客户端执 ...
- 【机器学习】--Kmeans从初识到应用
一.前述 Kmeans算法一般在数据分析前期使用,选取适当的k,将数据分类后,然后分类研究不同聚类下数据的特点. Kmeans算法是一种无监督的算法. 常用于分组,比如用户偏好. 二.概念及原理 Km ...