这篇对AQS做一个总结。

上一篇帖了很多AQS的代码,可以看出AQS的实现思路很简单,就是提供了获取acquire和释放操作release,提供了

1. 可中断和不可中断的版本

2. 可定时和不可定时的版本

3. 独享和共享的版本

看过之前实现各种自旋锁系列的同学应该知道,在自旋锁的实现中,获取锁和释放锁操作的逻辑基本如下:

自旋锁获取锁操作

while 状态不允许获取锁 {

自旋

}

进入锁之前设置某些状态

自旋锁释放锁操作

设置释放锁的状态

if (允许后续线程获取锁){

通知后续线程获取锁

}

而AQS的获取和释放操作也基本是这个逻辑,但是区别是它使用了阻塞操作,而不是自旋操作

AQS获取操作 acquire

while (状态不允许获取操作){

if(需要阻塞获取请求){

如果当前线程不在同步队列中,那么将其插入队列

阻塞当前线程

}else{

返回失败

}

}

可能更新同步器状态

如果线程位于同步队列,则将其移出队列

返回成功

}

AQS释放操作 release

更新同步器状态

if(新的状态允许某个被阻塞的线程获取成功){

解除队列中一个或多个线程的阻塞状态

}

要实现AQS的获取和释放功能,至少需要考虑三方面

1. 共享状态的原子修改,因为是在并发情况下

2. 线程的阻塞和唤醒,使用了Unsafe的park机制

3. 队列的管理,使用了两个队列,同步队列和条件队列。同步队列进行获取和释放操作,条件队列进行阻塞和唤醒操作

AQS抽象类负责管理上述的三个方面,而具体的同步器实现类则需要根据基类暴露出的状态相关的方法实现tryAcquire()和tryRelease()方法,以控制accquire和release操作。当状态满足时,tryAccquire方法要返回true,当新的状态允许后续线程获取时,tryRelease要返回true。另外这两类方法都支持一个int的状态参数,这个参数用于传递同步操作需要的状态,不是所有的同步器都需要。

关于获取操作和释放操作的具体算法细节,可以参考Doug Lea的这篇论文,详细分析了获取操作和释放操作的设计细节 The juc Synchronizer Framework中文翻译版

AQS提供了一个上层的基类提供了构建同步器的底层构件,可以方便地使用它来创建各种类型的同步器。后面会聊聊juc包种的同步器是如何使用AQS来构建的,理解了AQS之后,我们也可以方便地利用它来创建自定义的同步器解决实际问题。

聊聊高并发(二十三)解析java.util.concurrent各个组件(五) 深入理解AQS(三)相关推荐

  1. 聊聊高并发(二十二)解析java.util.concurrent各个组件(四) 深入理解AQS(二)

    上一篇介绍了AQS的基本设计思路以及两个内部类Node和ConditionObject的实现 聊聊高并发(二十一)解析java.util.concurrent各个组件(三) 深入理解AQS(一) 这篇 ...

  2. 聊聊高并发(二十九)解析java.util.concurrent各个组件(十一) 再看看ReentrantReadWriteLock可重入读-写锁

    上一篇聊聊高并发(二十八)解析java.util.concurrent各个组件(十) 理解ReentrantReadWriteLock可重入读-写锁 讲了可重入读写锁的基本情况和主要的方法,显示了如何 ...

  3. 聊聊高并发(二十五)解析java.util.concurrent各个组件(七) 理解Semaphore

    前几篇分析了一下AQS的原理和实现,这篇拿Semaphore信号量做例子看看AQS实际是如何使用的. Semaphore表示了一种可以同时有多个线程进入临界区的同步器,它维护了一个状态表示可用的票据, ...

  4. 聊聊高并发(二十九)解析java.util.concurrent各个组件(十一) 再看看ReentrantReadWriteLock可重入读-写锁...

    上一篇聊聊高并发(二十八)解析java.util.concurrent各个组件(十) 理解ReentrantReadWriteLock可重入读-写锁 讲了可重入读写锁的基本情况和基本的方法,显示了怎样 ...

  5. 聊聊高并发(二十一)解析java.util.concurrent各个组件(三) 深入理解AQS(一)

    AQS是AbstractQueuedSynchronizer的缩写,AQS是Java并包里大部分同步器的基础构件,利用AQS可以很方便的创建锁和同步器.它封装了一个状态,提供了一系列的获取和释放操作, ...

  6. 聊聊高并发(二十)解析java.util.concurrent各个组件(二) 12个原子变量相关类

    这篇说说java.util.concurrent.atomic包里的类,总共12个,网上有很多文章解析这几个类,这里挑些重点说说. 这12个类可以分为三组: 1. 普通类型的原子变量 2. 数组类型的 ...

  7. 聊聊高并发(十七)解析java.util.concurrent各个组件(一) 了解sun.misc.Unsafe类

    了解了并发编程中锁的基本原理之后,接下来看看Java是如何利用这些原理来实现各种锁,原子变量,同步组件的.在开始分析java.util.concurrent的源代码直接,首先要了解的就是sun.mis ...

  8. 聊聊高并发(二十八)解析java.util.concurrent各个组件(十) 理解ReentrantReadWriteLock可重入读-写锁

    这篇讲讲ReentrantReadWriteLock可重入读写锁,它不仅是读写锁的实现,并且支持可重入性. 聊聊高并发(十五)实现一个简单的读-写锁(共享-排他锁) 这篇讲了如何模拟一个读写锁. 可重 ...

  9. 聊聊高并发(二十七)解析java.util.concurrent各个组件(九) 理解ReentrantLock可重入锁

    这篇讲讲ReentrantLock可重入锁,JUC里提供的可重入锁是基于AQS实现的阻塞式可重入锁.这篇 聊聊高并发(十六)实现一个简单的可重入锁 模拟了可重入锁的实现.可重入锁的特点是: 1. 是互 ...

  10. 聊聊高并发(三十一)解析java.util.concurrent各个组件(十三) 理解Exchanger交换器

    这篇讲讲Exchanger交互器,它是一种比较特殊的两方(Two-Party)栅栏,可以理解成Exchanger是一个栅栏,两边一方是生产者,一方是消费者, 1. 生产者和消费者各自维护了一个容器,生 ...

最新文章

  1. Linux: CentOS 7下搭建高可用集群
  2. 使用webpack打包后,vscode中vue代码变白色的解决办法
  3. RPi 2B GPIO 测试
  4. 项目遇到的问题或处理办法
  5. 面试题如何实现一个IOC容器
  6. 高级转录组分析和R语言数据可视化课程全部转为视频课
  7. 可迭代对象与迭代器 0318 草稿
  8. Flask—10-项目部署(02)
  9. 如何防止抓包软件抓取我们网页的信息?
  10. C语言怎么实现熊猫上香中的系统错误提示,熊猫烧香的病毒是用什么程序语言编写的 原理是什么...
  11. 初学python_day05
  12. 串口uart编程——基于imx6ull
  13. AGND DGND PGND GND
  14. 2021年创新医疗器械盘点
  15. 不知道测试什么?你需要知道的软件测试类型和常识【经典长文】
  16. 使用pytorch模型学习框架easyocr模块识别行程码图片文字并使用Flask Web返回指定信息json字符串
  17. 辨析 dB、dBm、dBw
  18. 03 CoCos Creator 偏好设置中ndk配置
  19. 日志瘦身神操作:从5G优化到1G到底是怎么做到的!(荣耀典藏版)
  20. 啊 啊 啊 摆弄了半天 dreamweaver cs4终于弄成正版的啦

热门文章

  1. 深入理解linux文件系统( 理解inode与block,理解硬链接软链接,掌握恢复误删文件及其分析方法,掌握用户日志及其查询命令 )
  2. 网络层协议简介之ICMP和ARP
  3. 华硕计算机用户名默认,华硕路由器后台默认网址是多少
  4. python 2x可以打么_15分钟让你了解Python套路,看你能不能坚持的住
  5. python cpython关系_第3篇:CPython内部探究:PyASCIIObject的初始化
  6. 51单片机auxr寄存器_STC12C5A60S2单片机AD采样程序及其寄存器讲解
  7. java正则表达式去除xml标签之间的空格_HTML解析器——htmlparser2使用详解,换个姿势解析html和xml
  8. clojure java.jdbc_Clojure驱动的Web开发
  9. k歌的录音伴奏合成技术如何实现_2019年中国在线K歌行业市场现状,在线K歌用户女性占比较高...
  10. android dts配置_AndroidLinux关于DTS设备树源码的介绍