1.5w字,30图带你彻底掌握 AQS!(建议收藏)( 三 )
state 由于是多线程共享变量 , 所以必须定义成 volatile , 以保证 state 的可见性, 同时虽然 volatile 能保证可见性 , 但不能保证原子性 , 所以 AQS 提供了对 state 的原子操作方法 , 保证了线程安全 。
另外 AQS 中实现的 FIFO 队列(CLH 队列)其实是双向链表实现的 , 由 head, tail 节点表示 , head 结点代表当前占用的线程 , 其他节点由于暂时获取不到锁所以依次排队等待锁释放 。
所以我们不难明白 AQS 的如下定义:
public abstract class AbstractQueuedSynchronizerextends AbstractOwnableSynchronizerimplements java.io.Serializable {// 以下为双向链表的首尾结点 , 代表入口等待队列private transient volatile Node head;private transient volatile Node tail;// 共享变量 stateprivate volatile int state;// cas 获取 / 释放 state , 保证线程安全地获取锁protected final boolean compareAndSetState(int expect, int update) {// See below for intrinsics setup to support thisreturn unsafe.compareAndSwapInt(this, stateOffset, expect, update);}// ... }
AQS 源码剖析ReentrantLock 是我们比较常用的一种锁 , 也是基于 AQS 实现的 , 所以接下来我们就来分析一下 ReentrantLock 锁的实现来一探 AQS 究竟 。 本文将会采用图文并茂的方式让大家理解 AQS 的实现原理 , 大家在学习过程中 , 可以多类比一下上文中就诊的例子 , 相信会有助于理解 。
首先我们要知道 ReentrantLock 是独占锁 , 也有公平和非公平两种锁模式 , 什么是独占与有共享模式 , 什么又是公平锁与非公平锁
与独占锁对应的是共享锁 , 这两者有什么区别呢
独占锁:即其他线程只有在占有锁的线程释放后才能竞争锁 , 有且只有一个线程能竞争成功(医生只有一个 , 一次只能看一个病人)
共享锁:即共享资源可以被多个线程同时占有 , 直到共享资源被占用完毕(多个医生 , 可以看多个病人) , 常见的有读写锁 ReadWriteLock, CountdownLatch , 两者的区别如下
文章插图
什么是公平锁与非公平锁
还是以就医为例 , 所谓公平锁即大家取号后老老实实按照先来后到的顺序在侯诊室依次等待叫号 , 如果是非公平锁呢 , 新来的病人(线程)很霸道 , 不取号排队, 直接去抢先看病 , 占有医生(不一定成功)
文章插图
公平锁与非公平锁
本文我们将会重点分析独占 , 非公平模式的源码实现 , 不分析共享模式与 Condition 的实现 , 因为剖析了独占锁的实现 , 由于原理都是相似的 , 再分析共享与 Condition 就不难了 。
首先我们先来看下 ReentrantLock 的使用方法
// 1. 初始化可重入锁private ReentrantLock lock = new ReentrantLock();public void run() {// 加锁lock.lock();try {// 2. 执行临界区代码} catch (InterruptedException e) {e.printStackTrace();} finally {// 3. 解锁lock.unlock();}}
第一步是初始化可重入锁 , 可以看到默认使用的是非公平锁机制
public ReentrantLock() {sync = new NonfairSync();}
当然你也可以用如下构造方法来指定使用公平锁:
public ReentrantLock(boolean fair) {sync = fair ? new FairSync() : new NonfairSync();}
画外音: FairSync 和 NonfairSync 是 ReentrantLock 实现的内部类 , 分别指公平和非公平模式 , ReentrantLock ReentrantLock 的加锁(lock) , 解锁(unlock)在内部具体都是调用的 FairSync , NonfairSync 的加锁和解锁方法 。
- 小米的“一连指”,能否彻底点燃UWB消费级市场?
- 微信新增6个灵魂表情,捂脸哭彻底过时,裂开表情瞬间走红
- 只需2步,彻底关闭电脑里的弹窗广告,建议收藏
- 还在为被看见聊天记录而烦恼吗?,教你彻底清空聊天记录
- 美国防部注资6亿将5G军事化,彻底颠覆战争理念
- 人工智能如何彻底改变从IVR到销售辅导的商务电话
- 国外快递成功“入侵”,半年时间就日单千万!三通一达彻底慌了
- 比特币金融:“夸克链信”彻底玩完,币价跌至3毛钱,凉凉
- iPhone12值不值得买?一张图带你看完苹果新品发布会
- 让你彻底搞懂布隆过滤器!实现一个自己的BloomFilter