
课程咨询: 400-996-5531 / 投诉建议: 400-111-8989
认真做教育 专心促就业
在学习it科大的时候,有一个很特殊的问题就是,深入浅出AQS的条件队列这部分的至少,下面长沙ui设计培训老师就和大家说点题外话,我们一起来看,相比于独占锁跟共享锁,AbstractQueuedSynchronizer中的条件队列可能被关注的并不是很多,但它在阻塞队列的实现里起着至关重要的作用,同时如果想全面了解AQS,条件队列也是必须要学习的
深入浅出AQS之共享锁模式
一、使用场景介绍
区别于前面两篇文章,可能之前很多人都没有太在意AQS中的这块内容,所以这篇文章我们先来看下条件队列的使用场景:
上面的代码片段截取自LinkedBlockingQueue,是Java常用的阻塞队列之一。
从上面的代码可以看出,条件队列是建立在锁基础上的,而且必须是独占锁(原因后面会通过源码分析)。
二、执行过程概述
等待条件的过程:
在操作条件队列之前首先需要成功获取独占锁,不然直接在获取独占锁的时候已经被挂起了。
成功获取独占锁以后,如果当前条件还不满足,则在当前锁的条件队列上挂起,与此同时释放掉当前获取的锁资源。这里可以考虑一下如果不释放锁资源会发生什么?
如果被唤醒,则检查是否可以获取独占锁,否则继续挂起。
条件满足后的唤醒过程(以唤醒一个节点为例,也可以唤醒多个):
把当前等待队列中的第一个有效节点(如果被取消就无效了)加入同步队列等待被前置节点唤醒,如果此时前置节点被取消,则直接唤醒该节点让它重新在同步队列里适当的尝试获取锁或者挂起。
注:说到这里必须要解释一个知识点,整个AQS分为两个队列,一个同步队列,一个条件队列。只有同步队列中的节点才能获取锁。前面两篇独占锁共享锁文章中提到的加入队列就是同步队列。条件队列中所谓的唤醒是把节点从条件队列移到同步队列,让节点有机会去获取锁。
二、源码深入分析
下面的代码稍微复杂一点,因为它考虑了中断的处理情况。我由于想跟文章开头的代码片段保持一致,所以选取了该方法进行说明。如果只想看核心逻辑的话,那推荐读者看看awaitUninterruptibly()方法的源码。
三、总结
相比于独占锁跟共享锁,条件队列可能是最不受关注的了,但由于它是阻塞队列实现的关键组件,还是有必要了解一下其中的原理。其实我认为关键点有两条,第一是条件队列是建立在某个具体的锁上面的,第二是条件队列跟同步队列是两个队列,前者依赖条件唤醒后者依赖锁释放唤醒,了解了这两点以后搞清楚条件队列就不是什么难事了。
扫码加入0元课程试听报名!