大家好, 距离上一篇原创又有一个多星期来,这次给大家带来阻塞队列的深入分析。
对于阻塞队列在上一篇线程池的分析中有分析到,大家可以参考一下:[线程池全面分析] 。
那什么是阻塞队列呢?按照我个人的理解就是,队列他本身是一个容器,容器就是来装元素的,那么装元素就会有放元素和取元素的两个操作,而这个阻塞两个字就是体现在放元素和取元素两个操作;队列的另一个特性就是FIFO(first in first out)。
所以用一句话来概括阻塞队列就是:是一个支持阻塞式的插入和移除的FIFO队列:
那一定是阻塞吗?不一定,上面描述是支持,那么可以非阻塞吗,答案是可以的,它也可以支持当队列不满足插入或者移除元素的条件,会立即返回一个特殊值,表示这个操作是否成功,比如true和false。
一般阻塞队列比较常用于生产者与-消费者模式。比如:我上一篇写的线程池的文章中就有分析到。
阻塞队列充当生产者与-消费者模式的容器,生产者往阻塞队列里面添加数据,消费者从队列中获取数据进行消费。
那么,在Java中常用的几种阻塞队列有哪些呢?下面我们来详细的聊一聊具体阻塞队列有哪些?
先放一张阻塞队列的继承关系图:
最顶层的是Iterable,接下来的接口是Collection,对于Collection,我们对于它的印象更多的是集合的父接口,因为在Collection里面更多定义的是我们所熟悉的集合方法:
第三层就是Queue接口,在这个接口里面定义了队列的插入和移除的基本方法:
所以,要研究阻塞队列可以研究Queue以下的接口以及实现类就行了,在Queue接口下面就是BlockingQueue子接口,在这个子接口里面扩展了更多的对于阻塞队列的操作的方法,具体如下:
最下面的就是具体的阻塞队列的实现类,一共有七个:
对于阻塞队列主要研究的就是元素怎么进入队列里面,上面的BlockingQueue接口里面对于插入和移除都有好几个方法,那么这个方法又有什么不同呢?可以参考下面的表格:
那么对于阻塞队列,它又是怎么实现上面的特点的呢?下面我们通过源码分析的方式进行深入的剖析。
这里以ArrayBlockingQueue的源码进行深入的分析,其他几个的源码可以结合相关资料自行了解。
先来看看ArrayBlockingQueue的add操作,add操作是队列满的时候抛出以异常,源码实现挺简单的:
ArrayBlockingQueue的add操作是直接调用父类AbstractQueue的add操作:
add操作就是通过调用offer操作返回的特殊值进行判断实现,来看看offer的实现:
offer方法实现主要干了以下四件事:
enqueue方法是真正实现插入元素的动作,具体的源码实现如下:
上面我们聊到在ArrayBlockingQueue的源码实现里面使用Object[] items来存储元素,也就是上面源码实现的this.items,直接通过**items[putIndex] = x;**的方式将元素插入队列里面。
然后再判断putIndex是否已经达到队列的长度,若是已经达到队列长度就重新赋值为0。
最后记录count++ 也就是队列中元素的个数。这里有个比较有意思的就是notEmpty.signal() 方法,与它对应就是:notEmpty.await()
notEmpty是一个Condition类型的元素,对于Condition这里制作大致的介绍,后面的原创会详细的介绍。
在ArrayBlockingQueue源码实现里面有等待条件队列,分别是:notEmpty和notFull:
这两个的作用分别是:当向队列里面添加元素的时候或者向队列获取元素,队列已经满了或者队列为空,notEmpty可以在队列为空时,调用notEmpty.await(),阻塞线程:
当向队列里面添加了元素时,就会调用notEmpty.signal(),通知因为队列为空而等待的线程:
而notFull则是在队列满的时候,实现线程的通信,当向队列中添加元素的时候,队列满了,实现线程等待;或者从队列中获取了元素,则通知等待的线程往可以向队列中插入元素。
所以总的一句话来概括Condition的作用就是:实现线程之间的等待/通知机制的通信,其实等待通知机制我们直到在Object方法里面也有对应的wait/notify方法实现,具体两者的区别可以自己深入去了解,这一篇暂不做深入分析。
我们来看看Condition又是怎么实现等待/通知机制的呢?分别来看看await/signal的源码实现,signal跟踪到底层源码的实现,最终实现的重要方法是:LockSupport.unpark(node.thread):
LockSupport.unpark(node.thread) 这个就是真正的实现唤醒线程的操作,那么对应的await的方法,肯定是就是:LockSupport.park() 方法。再往下面研究就是native方法了:
所以Condition是通过LockSupport.park与LockSupport.unpark实现线程的等待通知机制。
研究过AQS的源码的人会知道,在AQS里面也会有Condition,因为AQS也有独占式锁,阻塞式的获取锁资源。
所以,到这里大家应该知道Condition的作用了吧,就是实现线程的等待与通知,可以用来实现阻塞式的资源获取。
我们来看看看put方法,阻塞式的:
从它的源码里面就能够显而易见的发现:当队列满的时候,调用notFull.await(),阻塞等待,直到线程被中断,或者有另外的线程唤醒notFull.signal()。这个方法比较简单,不过对于理解线程之间的通信,实现阻塞式的等待还是非常有帮助的,顺便给大家一张图:
图片来源于百度
最后来看看offer实现超时退出,具体源码如下:
具体的实现,还是调用notFull.awaitNanos(nanos),进行超时等待,而它的底层是调用LockSupport.parkNanos(this, nanosTimeout),最终还是回到了这个LockSupport类:
在超时退出方法offer里面有个有意思的就是这个lock.lockInterruptibly(),在ReentrantLock获取锁的方法有好几个。
分别有lock、tryLock、lockInterruptibly等,他们的区别就是lock是是阻塞的,tryLock是非阻塞(返回特殊值)、lockInterruptibly是阻塞可中断的:
在lock的源码中作者也有解释到:如果锁由另一个线程持有,则当前线程出于线程调度目的将被禁用,并处于休眠状态,直到获得锁为止,此时锁持有计数设置为1
所以lockInterruptibly方法在跳出,有以下几种可能:
在lockInterruptibly底层源码跟踪后也是通过**LockSupport.park(this)**方法来实现线程的阻塞:
所以很多并发的工具类底层实现都基本差不多(Condition、LockSupport),因为这些都是通用的,应用层的工具类都是通过各种已有的工具类堆叠起来的。
最后分享一波关于JVM知识总结的精美图片给你们,让你们卷一下,哈哈哈
好了今天的阻塞队列的知识就先分享到这里,我们下一期见 ,感谢大家!!!最后提前祝大家国庆快乐!!!
本文由哈喽比特于3年以前收录,如有侵权请联系我们。
文章来源:https://mp.weixin.qq.com/s/G3rs80jXO74VJli3pNZxPQ
京东创始人刘强东和其妻子章泽天最近成为了互联网舆论关注的焦点。有关他们“移民美国”和在美国购买豪宅的传言在互联网上广泛传播。然而,京东官方通过微博发言人发布的消息澄清了这些传言,称这些言论纯属虚假信息和蓄意捏造。
日前,据博主“@超能数码君老周”爆料,国内三大运营商中国移动、中国电信和中国联通预计将集体采购百万台规模的华为Mate60系列手机。
据报道,荷兰半导体设备公司ASML正看到美国对华遏制政策的负面影响。阿斯麦(ASML)CEO彼得·温宁克在一档电视节目中分享了他对中国大陆问题以及该公司面临的出口管制和保护主义的看法。彼得曾在多个场合表达了他对出口管制以及中荷经济关系的担忧。
今年早些时候,抖音悄然上线了一款名为“青桃”的 App,Slogan 为“看见你的热爱”,根据应用介绍可知,“青桃”是一个属于年轻人的兴趣知识视频平台,由抖音官方出品的中长视频关联版本,整体风格有些类似B站。
日前,威马汽车首席数据官梅松林转发了一份“世界各国地区拥车率排行榜”,同时,他发文表示:中国汽车普及率低于非洲国家尼日利亚,每百户家庭仅17户有车。意大利世界排名第一,每十户中九户有车。
近日,一项新的研究发现,维生素 C 和 E 等抗氧化剂会激活一种机制,刺激癌症肿瘤中新血管的生长,帮助它们生长和扩散。
据媒体援引消息人士报道,苹果公司正在测试使用3D打印技术来生产其智能手表的钢质底盘。消息传出后,3D系统一度大涨超10%,不过截至周三收盘,该股涨幅回落至2%以内。
9月2日,坐拥千万粉丝的网红主播“秀才”账号被封禁,在社交媒体平台上引发热议。平台相关负责人表示,“秀才”账号违反平台相关规定,已封禁。据知情人士透露,秀才近期被举报存在违法行为,这可能是他被封禁的部分原因。据悉,“秀才”年龄39岁,是安徽省亳州市蒙城县人,抖音网红,粉丝数量超1200万。他曾被称为“中老年...
9月3日消息,亚马逊的一些股东,包括持有该公司股票的一家养老基金,日前对亚马逊、其创始人贝索斯和其董事会提起诉讼,指控他们在为 Project Kuiper 卫星星座项目购买发射服务时“违反了信义义务”。
据消息,为推广自家应用,苹果现推出了一个名为“Apps by Apple”的网站,展示了苹果为旗下产品(如 iPhone、iPad、Apple Watch、Mac 和 Apple TV)开发的各种应用程序。
特斯拉本周在美国大幅下调Model S和X售价,引发了该公司一些最坚定支持者的不满。知名特斯拉多头、未来基金(Future Fund)管理合伙人加里·布莱克发帖称,降价是一种“短期麻醉剂”,会让潜在客户等待进一步降价。
据外媒9月2日报道,荷兰半导体设备制造商阿斯麦称,尽管荷兰政府颁布的半导体设备出口管制新规9月正式生效,但该公司已获得在2023年底以前向中国运送受限制芯片制造机器的许可。
近日,根据美国证券交易委员会的文件显示,苹果卫星服务提供商 Globalstar 近期向马斯克旗下的 SpaceX 支付 6400 万美元(约 4.65 亿元人民币)。用于在 2023-2025 年期间,发射卫星,进一步扩展苹果 iPhone 系列的 SOS 卫星服务。
据报道,马斯克旗下社交平台𝕏(推特)日前调整了隐私政策,允许 𝕏 使用用户发布的信息来训练其人工智能(AI)模型。新的隐私政策将于 9 月 29 日生效。新政策规定,𝕏可能会使用所收集到的平台信息和公开可用的信息,来帮助训练 𝕏 的机器学习或人工智能模型。
9月2日,荣耀CEO赵明在采访中谈及华为手机回归时表示,替老同事们高兴,觉得手机行业,由于华为的回归,让竞争充满了更多的可能性和更多的魅力,对行业来说也是件好事。
《自然》30日发表的一篇论文报道了一个名为Swift的人工智能(AI)系统,该系统驾驶无人机的能力可在真实世界中一对一冠军赛里战胜人类对手。
近日,非营利组织纽约真菌学会(NYMS)发出警告,表示亚马逊为代表的电商平台上,充斥着各种AI生成的蘑菇觅食科普书籍,其中存在诸多错误。
社交媒体平台𝕏(原推特)新隐私政策提到:“在您同意的情况下,我们可能出于安全、安保和身份识别目的收集和使用您的生物识别信息。”
2023年德国柏林消费电子展上,各大企业都带来了最新的理念和产品,而高端化、本土化的中国产品正在不断吸引欧洲等国际市场的目光。
罗永浩日前在直播中吐槽苹果即将推出的 iPhone 新品,具体内容为:“以我对我‘子公司’的了解,我认为 iPhone 15 跟 iPhone 14 不会有什么区别的,除了序(列)号变了,这个‘不要脸’的东西,这个‘臭厨子’。