4.从AbstractQueuedSynchronizer(AQS)说起(3)——AQS结语
前两节的内容《2.从AbstractQueuedSynchronizer(AQS)说起(1)——独占模式的锁获取与释放》 、《3.从AbstractQueuedSynchronizer(AQS)说起(2)——共享模式的锁获取与释放》对AQS同步器已经有了一个大致的了解,从独占模式和共享模式来解析了AQS的两个基本方面,一个是同步状态的获取,另外一个是同步状态的释放,这是AQS最基本的特性,前面两节都是以阻塞的形式获取同步状态,但实际上AQS还能超时等待获取同步状态,或者非阻塞的方式获取同步状态。
以下是AQS锁定义的所有情况下同步状态的获取与释放(粗体为前两节已经讨论过),有了前两篇的解析,实际上剩余的方法几乎已经是换汤不换药。在这里就不再代码的具体分析,而我希望是在真正解读其子类的时候再返回来解析。
|
AbstractQueuedSynchronizer |
|
|
public final void acquire(int arg) |
独占模式下阻塞获取同步状态,成功获取则返回,失败则进入同步队列等待。(例:ReentrantLock.lock) |
|
public final void acquireInterruptibly(int arg) |
该方法与acquire类似,唯一不同的是如果当前线程被中断,该方法会抛出InterruptedException并返回,也就是说如果当前线程不被中断则和acquire一样。(例:ReentrantLock.lockInterruptibly) |
|
public final boolean tryAcquire(int arg, long nanosTimeOut) |
该方法在acquireInterruptibly的基础上增加了超时限制,如果当前线程在超时时间内获取到同步状态则返回true,获取到则返回false。(例:ReentrantLock.tryLock) |
|
public final acquireShared(int arg) |
共享模式下阻塞获取同步状态,成功获取则返回,失败则进入同步队列。(例:ReentrantReadWriteLock.unlock) |
|
public final acquireSharedInterruptibly(int arg) |
与acquireShared不同是此方法响应中断,与acquireInterruptibly类似,不同是的此方法是在共享模式下。(例:ReentrantReadWriteLock.lockInterruptibly) |
|
public final tryAcquireSharedNanos(int arg, long nanos) |
在acquireSharedInterruptibly基础上增加了超时限制,同样是在共享模式下。(例:ReentrantReadWriteLock.tryAcquireSharedNanos) |
|
public final boolean release(int arg) |
独占模式下释放同步状态,释放之后会将同步队列中的第一个包含的线程唤醒 |
|
public final boolean releaseShared(int arg) |
共享模式下释放同步状态 |
以下是AQS中给提供的获取同步状态等相关的方法:
|
AbstractQueuedSynchronizer |
|
|
public final boolean hasQueuedThreads() |
同步队列中是否有等待线程。 |
|
public final boolean hasContended() |
查询是否其他线程也曾争则获取此同步器,也就是说acquire是否已经阻塞,是则返回true。 |
|
public final Thread getFirstQueuedThread() |
返回当前同步队列中的第一个线程,米有则返回null。 |
|
public final boolean isQueued(Thread thread) |
线程是否已经在等待队列中,是则返回true。 |
|
final boolean apparentlyFirstQueuedIsExclusive() |
(包级可见)同步队列中第一个等待节点是否为独占模式 |
|
public final boolean hasQueuedPredecessors() |
查询是否有其他线程获取同步状态的时间大于当前线程,用于公平锁的实现。 |
|
public final int getQueueLength() |
返回同步队列的估计长度,该方法用于监视系统状态,而非同步控制。 |
|
public final Collection<Thread> getQueuedThreads() |
获取同步队列线程集合,同样是一个估计值。 |
|
public final Collection<Thread> getWaitingThreads(ConditionObject condition) |
获取在等等队列中的线程集合,估计值。 |
|
public final Collection<Thread> getExclusiveQueuedThreads() |
获取同步队列中独占模式线程集合,估计值。 |
|
public final Collection<Thread> getSharedQueuedThreads() |
获取同步队列中共享模式线程集合,同估计值。 |
|
final isOnSyncQueue(Node node) |
当前节点是否在sync等待队列中 |
以上方法或多或少再其子类有用到,具体的实现都不复杂,我们在这里也不对其一一做出分析,而是在具体分析到AQS的子类时,我们再回过头来看方法的实现。
最后我们再来看看子类可以重写的方法,这些方法在前两节中有提到过:
|
AbstractQueuedSynchronizer |
|
|
protected boolean tryAcquire(int arg) |
子类可实现在独占模式下获取同步状态的具体方法。 |
|
protected boolean tryRelease() |
子类可实现在独占模式下释放同步状态的具体方法。 |
|
protected int tryAcquireShared(int arg) |
子类可实现在共享模式下获取同步状态的具体方法。 |
|
protected int tryReleaseShared() |
子类可实现在共享模式下释放同步状态的具体方法。 |
|
protected boolean isHeldExclusively() |
当前同步器是否在独占模式下被线程占用,一般表示该方法是否被当前线程所独占。 |
Java并发包的第一个源码解读并不顺利,起初是想以Lock开头,但发现AQS不甚了解,继而决定从AQS入手。而真正从AQS入手过后发现很多原理及方法并不熟悉,又想从其子类之一ReentrantLock$Sync由下往上,但发现还是动不了脑子和笔,无奈陷入了停滞。最终决定由上往下进行解读,有的地方需要子类或者其他类做解释的时候要么跳过,要么一句话带过。在查找AQS的相关资料时,我发现其实源代码就是一个很好的“老师”,作者实际上已经将其实现的原理和过程以及设计都已经描述在其中,但又出现一个问题,注释都是英文,很多地方看不懂。网上有关AQS的解读都没有成套成体系的资料,于是开始将注意力转向书籍,先是查阅《Java并发编程实战》也许对于外国人来说源码中注释里已经写得很清楚的东西就不用再阐述了,而我正是需要最最基础的“注释翻译”。再查阅《Thinking in Java》更是没有我想要的东西,再看看其他的书均没有。突然想起有一个国人写的书《Java并发编程的艺术》,看了看目录决定入手,这本书的确对我入门Java并发包的源码有很大的帮助,尽管它不想《Java并发编程实战》这么经典、耐看,但是它作为入门级却有很大的帮助,文中的不少分析就是结合这本书以及源码才让我得以比较顺利的开展第一个Java并发包的AbstractQueuedSynchronizer源码解读。源码的阅读也许就是这样,跳过来跳过去,这个类继承,那个类实现,相互交叉耦合,很难一下就能读懂作者所要想表达的意思,坚持读下去,一定会豁然开朗。
4.从AbstractQueuedSynchronizer(AQS)说起(3)——AQS结语的更多相关文章
- Java并发框架——AQS之如何使用AQS构建同步器
AQS的设计思想是通过继承的方式提供一个模板让大家可以很容易根据不同场景实现一个富有个性化的同步器.同步器的核心是要管理一个共享状态,通过对状态的控制即可以实现不同的锁机制.AQS的设计必须考虑把复杂 ...
- Java并发框架——AQS之怎样使用AQS构建同步器
AQS的设计思想是通过继承的方式提供一个模板让大家能够非常easy依据不同场景实现一个富有个性化的同步器.同步器的核心是要管理一个共享状态,通过对状态的控制即能够实现不同的锁机制. AQS的设计必须考 ...
- 别走!这里有个笔记:图文讲解 AQS ,一起看看 AQS 的源码……(图文较长)
前言 AbstractQueuedSynchronizer 抽象队列同步器,简称 AQS .是在 JUC 包下面一个非常重要的基础组件,JUC 包下面的并发锁 ReentrantLock CountD ...
- 2.从AbstractQueuedSynchronizer(AQS)说起(1)——独占模式的锁获取与释放
首先我们从java.util.concurrent.locks包中的AbstraceQueuedSynchronizer说起,在下文中称为AQS. AQS是一个用于构建锁和同步器的框架.例如在并发包中 ...
- AQS框架源码分析-AbstractQueuedSynchronizer
前言:AQS框架在J.U.C中的地位不言而喻,可以说没有AQS就没有J.U.C包,可见其重要性,因此有必要对其原理进行详细深入的理解. 1.AQS是什么 在深入AQS之前,首先我们要搞清楚什么是AQS ...
- 8.初识Lock与AbstractQueuedSynchronizer(AQS)
1. concurrent包的结构层次 在针对并发编程中,Doug Lea大师为我们提供了大量实用,高性能的工具类,针对这些代码进行研究会让我们对并发编程的掌握更加透彻也会大大提升我们队并发编程技术的 ...
- AbstractQueuedSynchronizer(AQS)源码解析
关于AQS的源码解析,本来是没有打算特意写一篇文章来介绍的.不过在写本学期课程作业中,有一门写了关于AQS的,而且也画了一些相关的图,所以直接拿过来分享一下,如有错误欢迎指正. ...
- 初识Lock与AbstractQueuedSynchronizer(AQS)
本人免费整理了Java高级资料,涵盖了Java.Redis.MongoDB.MySQL.Zookeeper.Spring Cloud.Dubbo高并发分布式等教程,一共30G,需要自己领取.传送门:h ...
- 全网最详细的AbstractQueuedSynchronizer(AQS)源码剖析(一)AQS基础
AbstractQueuedSynchronizer(以下简称AQS)的内容确实有点多,博主考虑再三,还是决定把它拆成三期.原因有三,一是放入同一篇博客势必影响阅读体验,而是为了表达对这个伟大基础并发 ...
随机推荐
- Nginx编译参数
configure arguments: --with-cc-opt='-g -O2 -fPIE -fstack-protector //设置额外的参数将被添加到CFLAGS变量.(FreeBSD或者 ...
- my first blogs(我的处女博)
末夏的夕阳送走一批批下班的人,些许的轻风给一天烦躁的心带来一丝丝的清凉.我倒是挺喜欢在这种天气,提前下了公交车然后漫步回家.这样我能多点时间回顾一天的事情,俗话说是思考人生. 不知不觉毕业两年多了,在 ...
- 六行python代码的爱心曲线
前些日子在做绩效体系的时候,遇到了一件囧事,居然忘记怎样在Excel上拟合正态分布了,尽管在第二天重新拾起了Excel中那几个常见的函数和图像的做法,还是十分的惭愧.实际上,当时有效偏颇了,忽略了问题 ...
- jsel、tl是什么
el 表达式是什么? * sun 制订的一种用于计算的一种规则,可以给元素赋值,也可以直接输出 el表达式:${el表达式}实验1:简单的使用el表达式获取值<%request.setAttri ...
- SQL Server数据库的存储过程中定义的临时表,真的有必要显式删除临时表(drop table #tableName)吗?
本文出处:http://www.cnblogs.com/wy123/p/6704619.html 问题背景 在写SQL Server存储过程中,如果存储过程中定义了临时表,有些人习惯在存储过程结束的时 ...
- web前端概念巩固(一)
h5: 1.web语义化 Web语义化是指在进行HTML结构.表现.行为设计时,尽量使用语义化的标签,使程序代码简介明了,易于进行Web操作和网站SEO,方便团队协作的一种标准,以图实现一种" ...
- Webpack模块加载器
一.介绍 Webpack是德国开发者 Tobias Koppers 开发的模块加载器,它能把所有的资源文件(JS.JSX.CSS.CoffeeScript.Less.Sass.Image等)都作为模块 ...
- js错误问题 The operation is insecure.
问题: 当我使用canvas的ctx.getImageData 方法时,js报错,错误是 The operation is insecure. 解决: 我使用ctx.getImageData获取can ...
- java 集合框架(TreeSet操作,自动对数据进行排序,重写CompareTo方法)
/*TreeSet * treeSet存入数据后自动调用元素的compareTo(Object obj) 方法,自动对数据进行排序 * 所以输出的数据是经过排序的数据 * 注:compareTo方法返 ...
- centos7安装redis3.0和phpredis扩展详细教程(图文)
整理一下centos7安装redis3.0和phpredis扩展的过程,有需要的朋友可以拿去使用. 一.安装redis3.0 1.安装必要的包 yum install gcc 2.centos7安装r ...