AQS是什么
AbstractQueuedSynchronizer
是一个抽象的队列同步器,AQS利用模板方法模式
解决了开发者在实现同步器时的复杂问题,提供了一个通用的加锁解锁框架。
AQS执行原理
AQS为实现的同步器提供了通用的执行框架,定义了对资源state
的获取和释放流程。AQS核心思想是在CLH锁的基础上进行优化的
CLH锁
自旋:线程节点循环查询prev节点状态
单向队列:后面节点主动查询前节点状态
CLH锁 是一种是基于逻辑队列非线程饥饿的一种自旋公平锁,由 Craig、Landin 和 Hagersten三位大佬的发明,因此命名为CLH锁。
在并发情况下,多个线程在对共享资源进行请求时,发现资源已被占用,则会将请求锁的线程构造成一个单向队列中的节点;每一个线程节点通过自旋的形式访问前一个节点的状态,只有前节点锁释放后,当前节点才能获取锁。
存在的问题:长时间的自旋消耗CPU过大,会导致性能问题。
- 节点示意图
- 执行逻辑
AQS的实现
AQS在CLH的基础上进行了优化,使得对资源的占用,以及CPU的消耗降低
-
自旋+阻塞:因为大量的自旋占用资源较多,所以AQS在构造节点后,对线程进行阻塞等待唤醒
- AQS加锁:在并发请求共享资源时,判断头结点是否为空,
- 为空则将当前线程构造为头结点,添加到队列中,继续向下执行;
- 如果不是头结点,添加到队列中,并且阻塞,等待唤醒。
- AQS解锁:获取头节点信息,更改节点状态值,唤醒next节点线程
- AQS加锁:在并发请求共享资源时,判断头结点是否为空,
-
双向队列:AQS队列节点是一个具有
prev
next
两个属性的节点 -
加锁流程