AQS系列
1、AQS核心原理之
2、ReentrantLock 原理及示例
文章目录
- AQS系列
- 一、什么是AQS?
- 二、AQS特性
- 三、AQS内部维护 state
- 四、队列
- 4.1 同步等待队列
- 4.2 条件等待队列
- 5、总结
一、什么是AQS?
AQS全称是 AbstractQueuedSynchronizer(抽象对了同步器),是一个抽象类,在 juc(java.util.concurrent) 包下面,Java 并发编程核心都在这个包下面,大多数同步器实现都是围绕着共同的基础行为,比如说:等待队列、条件队列、独占获取、共享队列等,而这个行为就是基于 AbstractQueuedSynchronizer 实现,AQS是定义了一套多线程访问共享资源的同步器框架,也是一个依赖于状态(state)的同步器。
二、AQS特性
- 阻塞等待队列:AQS内部是通过一个 Node 类来组成一个队列,不管是条件队列还是CLH等待队列。
- 共享 / 独占:在 Node 类中定义 共享模式、独占模式;独占模式下只有一个线程能执行,比如 ReentrantLock, 共享模式下多个线程同时执行,比如 Semaphore、CountDownLatch。
- 公平 / 非公平:可以设置公平竞争资源还是非公平。
- 可重入:因为是通过 state 标记状态的,可以重复加锁。
- 允许中断:AQS 中判断当前线程是否是中断状态。
三、AQS内部维护 state
前面说过,AQS 内部其实就是靠一个属性成员 state 来维护状态的,state 的定义是这样的 volatile int state,是通过 volatile 修饰的,确保状态的改变每个线程都可以及时感知到 state 值的变化;
state 表示资源的可用状态,提供了三种访问方式:
- getState():获取状态的值,如果是 0 则资源可用。
- setState():设置状态值,相当于加锁。
- compareAndSetState():比较替换,原子操作。
四、队列
4.1 同步等待队列
AQS 中的同步等待队列也称 CLH 队列,CLH 队列是 Craig、Landing、Hagersten 三人发明的基于双向链表结构的队列,是 FIFO(先入先出)等待队列。
4.2 条件等待队列
Condition 是一个多线程间协调通信的工具类,在某个或者某些线程一起等待某个条件成立,只有该条件成立是则这些线程才被唤醒重新争夺锁。
原理流程图
5、总结
AQS 是 Doug Lea 写出来的,基于 state 状态 和 队列的一个多线程框架,很多实现都是基于 AQS 实现的,比如说 ReentrantLock 是一个独占方式执行,每次只有一个线程执行,还有 Semaphore、 CountDownLatch 都是 共享的方式执行,每次有多个线程同时执行,我在做数据推送的工作是总喜欢用它们,效率杠杠的。
这篇文章简单介绍了 AQS 原理,至于源码后面慢慢看,确实逻辑很复杂也能难懂,先学会使用再看源码吧。
昨天还是 2022-12-31,今天是 2023-01-01,大家新年快乐 ^ _ ^ !!!