10.1 如何学习AQS
10.1.1学习AQS的思路
- 学习AQS的目的主要是想理解原理、提高技术,以及应对面试
- 先从应用层面理解为什么需要他如何使用它,然后再看一看我们Java代码的设计者是如何使用它的了解它的应用场景
这样之后我们再去分析它的结构,这样的话我们就学习得更加轻松了
10.1.2 为什么需要AQS
- 锁和协作类有共同点:闸门
- 我们已经学过了ReentrantLock和Semaphore ,有没有发现它们有共同点?很相似?
事实上,不仅是ReentrantLock和Semaphore ,包括CountDownLatch、ReentrantReadWriteLock都有这样类似的”协作”(或者叫“同步”)功能,其实,它们底层都用了一个共同的基类,这就是AQS
因为上面的那些协作类,它们有很多工作都是类似的,所以如果能提取出一个工具类,那么就可以直接用,对于ReentrantLock和Semaphore而言就可以屏蔽很多细节,只关注它们自己的“业务逻辑”就可以了
10.2 Semaphore和AQS的关系
Semaphore内部有一个Sync类,Sync继承了AQS,CountDownLatch也是一样的。
Semaphore内部有一个Sync对象。
Sync继承了AQS,ReentrantLock也是一样的。
10.3 比喻:HR和AQS的职责统一
比喻:群面、单面
相同点:
- 安排就坐、叫号、先来后到等HR的工作就是AQS做的工作。
- 面试官利用AQS,面试官就是类似于AQS
- 去管面试者需要一个地方坐着休息 ,这些都交给HR去做
具体到工具类
- Semaphore : 一个人面试完了以后,后一个人才能进来继续面试
- CountDownLatch : 群面,等待10人到齐
- Semaphore、CountDownLatch这些同步 工具类,要做的,就只是写下自己的“要人”规则。比如是”出一一个,进一个”或者说”凑齐10人,一起面试”
- 剩下的招呼面试者的脏活累活交给AQS来做
如果没有AQS
- 就需要每个协作工具自己实现:
- 同步状态的原子性管理
- 线程的阻塞与解除阻塞
- 队列的管理
在并发场景下,自己正确且高效实现这些内容,是相当有难度的,所以我们用AQS来帮我们把这些脏活累活都搞定,我们只关注业务逻辑就够了
AQS的作用
- AQS是一个用于构建锁、同步器、协作工具类的工具类(框架)。有了AQS以后,更多的协作工具类都可以很方便得被写出来
- 一句话总结:有了AQS ,构建线程协作类就容易多了。
AQS的重要性、地位
- AbstractQueuedSynchronizer是Doug Lea写的,从JDK1.5加入的一个基于FIFO等待队列实现的一个用于实现同步器的基础框架,我们用IDE看AQS的实现类,可以发现实现类有以下这些:
使用到AQS的地方
10.4 AQS的三要素
AQS内部原理解析
- AQS最核心的就是三大部分:
- state
- 控制线程抢锁和配合的FIFO队列
- 期望协作工具类去实现的获取/释放等重要方法
state状态
- 这里的state的具体含义,会根据具体实现类的不同而不同,比如在Semaphore里,它表示”剩余的许可证的数量”, 而在CountDownLatch里,它表示“还需要倒数的数量’
- state是volatile修饰的,会被并发地修改,所以所有修改state的方法都需要保证线程安全,比如getState、setState以及compareAndSetState操作来读取和更新这个状态。这些方法都依赖于j.u.c.atomic包的支持
state状态
- 在ReentrantLock中
- state用来表示”锁”的占有情况,包括可重入计数
- 当state的值为0的时候,标识改Lock不被任何线程所占有
10.5 AQS简要分析
release
唤醒所有线程。
10.6 许可证的颁发
semaphore实现相对简单。
10.7 AQS在ReentrantLock
10.8 DIY一次性门闩
10.9 AQS核心思路
10.10 AQS补充材料(选修)
以下文章是关于AQS源码分析的,通常并不要求掌握,我找了一些优质学习资源,提供给小伙伴参考:
美团技术团队《从ReentrantLock的实现看AQS的原理及应用》:https://mp.weixin.qq.com/s/sA01gxC4EbgypCsQt5pVog
老钱《打通 Java 任督二脉 —— 并发数据结构的基石》:https://juejin.im/post/5c11d6376fb9a049e82b6253
HongJie《一行一行源码分析清楚AbstractQueuedSynchronizer》:https://javadoop.com/post/AbstractQueuedSynchronizer
爱吃鱼的KK《AbstractQueuedSynchronizer 源码分析 (基于Java 8)》:https://www.jianshu.com/p/e7659436538b
waterystone《Java并发之AQS详解》:https://www.cnblogs.com/waterystone/p/4920797.html
英文论文的中文翻译:https://www.cnblogs.com/dennyzhangdd/p/7218510.html
AQS作者的英文论文:http://gee.cs.oswego.edu/dl/papers/aqs.pdf