深入理解AQS–jdk层面管程实现【管程详解的补充】

什么是AQS

1.java.util.concurrent包中的大多数同步器实现都是围绕着共同的基础行为,比如等待队列、条件队列、独占获取、共享获取等,而这些行为的抽象就是基于AbstractQueuedSynchronizer(简称AQS)实现的,AQS是一个抽象同步框架,可以用来实现一个依赖状态的同步器。

2.JDK中提供的大多数的同步器如Lock, Latch, Barrier等,都是基于AQS框架来实现的

【1】一般是通过一个内部类Sync继承 AQS

【2】将同步器所有调用都映射到Sync对应的方法

AQS具备的特性:

1.阻塞等待队列 ,2.共享/独占,3.公平/非公平,4.可重入,5.允许中断

AQS定义两种资源共享方式

2.Share-共享,多个线程可以同时执行,如Semaphore/CountDownLatch

AQS定义两种队列

【1】AQS当中的同步等待队列也称CLH队列,CLH队列是Craig、Landin、Hagersten三人发明的一种基于双向链表数据结构的队列,是FIFO先进先出线程等待队列,Java中的CLH队列是原CLH队列的一个变种,线程由原自旋机制改为阻塞机制。

【2】AQS 依赖CLH同步队列来完成同步状态的管理:

1)当前线程如果获取同步状态失败时,AQS则会将当前线程已经等待状态等信息构造成一个节点(Node)并将其加入到CLH同步队列,同时会阻塞当前线程

2)当同步状态释放时,会把首节点唤醒(公平锁),使其再次尝试获取同步状态。

3)通过signal或signalAll将条件队列中的节点转移到同步队列。(由条件队列转化为同步队列)

【3】图示:

【1】AQS中条件队列是使用单向列表保存的,用nextWaiter来连接:

1)调用await方法阻塞线程;

2)当前线程存在于同步队列的头结点,调用await方法进行阻塞(从同步队列转化到条件队列)

1)值为0,初始化状态,表示当前节点在sync队列中,等待着获取锁。

2)CANCELLED,值为1,表示当前的线程被取消;

3)SIGNAL,值为-1,表示当前节点的后继节点包含的线程需要运行,也就是unpark;

4)CONDITION,值为-2,表示当前节点在等待condition,也就是在condition队列中;

5)PROPAGATE,值为-3,表示当前场景下后续的acquireShared能够得以执行;

源码详解(将源码拆分为三块, 抽象同步器AbstractQueuedSynchronizer类,节点Node类,条件对象ConditionObject类 )

1.属性值解析

2.方法解析

1.代码展示

1.代码展示

2.发现说明

【1】在Condition中,用await()替换wait(),用signal()替换notify(),用signalAll()替换notifyAll(),传统线程的通信方式,Condition都可以实现,这里注意,Condition是被绑定到Lock上的,要创建一个Lock的Condition必须用newCondition()方法。Condition的强大之处在于,对于一个锁,我们可以为多个线程间建立不同的Condition。如果采用Object类中的wait(), notify(), notifyAll()实现的话,当写入数据之后需要唤醒读线程时,不可能通过notify()或notifyAll()明确的指定唤醒读线程,而只能通过notifyAll唤醒所有线程,但是notifyAll无法区分唤醒的线程是读线程,还是写线程。所以,通过Condition能够更加精细的控制多线程的休眠与唤醒。

【2】但,condition的使用必须依赖于lock对象,通过lock对象的newCondition()方法初始化一个condition对象。

1.属性值解析

2.方法解析

【1】核心await方法

【2】核心signal方法与signalAll方法

Original: https://www.cnblogs.com/chafry/p/16756929.html
Author: 忧愁的chafry
Title: 深入理解AQS–jdk层面管程实现【管程详解的补充】

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/801364/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球