最新要闻
- 焦点热议:历史总是惊人地相似:复古主机Atari VCS宣告停产 一个时代终结
- 网友称考研民宿房费暴涨近20倍 店家:每年都一样
- 中国企业站稳全球LCD市场!李东生:TCL部分技术领先三星
- 消息!超可爱!《王者荣耀》梦奇赛年皮肤来了 特效贼棒
- 环球热讯:《王者荣耀》《合金弹头》联动:联名首发新英雄莱西奥
- 【世界播资讯】高能吸水 洁丽雅纯棉毛巾:15.9元/3条
- 今日报丨Intel显卡事业部突然解散!掌门人Raja回归首席架构师
- 全球新消息丨国内油价要止步“三连跌”!元旦后或迎新一轮价格上调
- 世界微头条丨比iPhone 14 Pro Max还轻 OPPO Find N2明天首销:7999元
- 每日时讯!入口脆甜 林家铺子乌龙茶蜜桃罐头19.9元四罐
- 今日讯!5年了 网易云音乐终于撕下了“网抑云”标签
- 全球热资讯!羊被冻死牧羊犬贴身供暖试图唤醒 网友:边牧聪明又有情
- 每日速读!山东一地120和119到路口秒变绿灯 网友:建议全国推广
- 天天看点:腾讯智能车技术花样用 数万人疯狂点赞转发
- 世界热资讯!小米史上最强!雷军确认小米13 Pro支持Wi-Fi 7:国内认证后开放
- 快报:高帧畅玩《巫师3》!满血3060游戏本华硕天选3双旦入手7599 性价比超高
手机
iphone11大小尺寸是多少?苹果iPhone11和iPhone13的区别是什么?
警方通报辅警执法直播中被撞飞:犯罪嫌疑人已投案
- iphone11大小尺寸是多少?苹果iPhone11和iPhone13的区别是什么?
- 警方通报辅警执法直播中被撞飞:犯罪嫌疑人已投案
- 男子被关545天申国赔:获赔18万多 驳回精神抚慰金
- 3天内26名本土感染者,辽宁确诊人数已超安徽
- 广西柳州一男子因纠纷杀害三人后自首
- 洱海坠机4名机组人员被批准为烈士 数千干部群众悼念
家电
JDK源码分析实战系列-PriorityBlockingQueue
前言
可以通过分析PriorityBlockingQueue来了解JUC中的线程安全的队列实现的一些套路,这些套路会在JUC中其他数据结构实现上反复出现,从而可以更合理的了解那些实现机制背后通用的部分。
【资料图】
BlockingQueue
A Queue that additionally supports operations that wait for the queue to become non-empty when retrieving an element, and wait for space to become available in the queue when storing an element.
阻塞队列,这个接口就非常重要,它是定义了阻塞队列需要实现的接口能力,它的子类有ArrayBlockingQueue
,LinkedBlockingQueue
,PriorityBlockingQueue
等。
作为队列的扩展,扩展的核心能力是阻塞能力,这个阻塞能力表示:当队列空了的时候,获取元素的操作需要阻塞,等待队列有存储新的元素进入。这里容易产生一个误解:认为BlockingQueue也包含了当队列满的时候,放入操作阻塞的能力,这一点并不是BlockingQueue的能力要求,这和子类实现的是有界或无界队列有关。
PriorityBlockingQueue
PriorityBlockingQueue的数据结构的实现是和PriorityQueue是一致的,完全可以参考前一篇的文章,这里重点是了解清楚通过锁来保证线程安全的队列的实现方式,知道了这些知识点,再要理解JUC中其他的队列的实现简直轻而易举。
实现线程安全的关键两个属性:
/***Lockusedforallpublicoperations*/privatefinalReentrantLocklock;/***Conditionforblockingwhenempty*/privatefinalConditionnotEmpty;
各个操作的时候都执行lock.lock();
锁住,操作结束执行lock.unlock();
解锁。
比如简单的查看元素数量的方法:
publicintsize(){finalReentrantLocklock=this.lock;lock.lock();try{returnsize;}finally{lock.unlock();}}
有了锁,实现线程安全的操作变得简单而不易出错。下面我们看一些关键的操作方法的实现。
offer
offer
方法将一个元素放入队列,对于一个无界限队列来说,需要处理扩容情况。而作为阻塞队列,当放入元素意味着此时队列不是空队列,那么就需要通知那些来获取队列元素因为空队列而阻塞的线程,继续执行获取元素的操作。
publicbooleanoffer(Ee){if(e==null)thrownewNullPointerException();finalReentrantLocklock=this.lock;lock.lock();intn,cap;Object[]array;//扩容逻辑while((n=size)>=(cap=(array=queue).length))tryGrow(array,cap);try{Comparatorcmp=comparator;if(cmp==null)siftUpComparable(n,e,array);elsesiftUpUsingComparator(n,e,array,cmp);size=n+1;//唤醒线程notEmpty.signal();}finally{lock.unlock();}returntrue;}
对于一个元素的位置摆放和优先级队列是一致的,完全可以参考前面一篇PriorityQueue
。
take
take方法尝试获取队列头节点的元素,如果为空,就阻塞线程等待,直到队列有元素再唤醒继续执行获取动作。这个Condition notEmpty内部机制可以参考前面的文章
publicEtake()throwsInterruptedException{finalReentrantLocklock=this.lock;lock.lockInterruptibly();Eresult;try{while((result=dequeue())==null)//等待唤醒notEmpty.await();}finally{lock.unlock();}returnresult;}
通过notEmpty
,实现了阻塞队列的核心能力,那就是当获取元素的时候队列空了阻塞线程和当队列有元素的时候进行唤醒动作。这一点在其他阻塞队列中也这样实现,另外,因为这是个无界队列,并不会发生队列满的情况,所以就没有在放入元素的时候处理阻塞的逻辑,而那些有界队列就需要处理这种情况,当然,处理起来也非常简单,再来一个标记队列满了的Condition
就可以了。
扩容
这种队列需要扩容,经过前面的一篇,我们已经不再陌生,而对于一个线程安全的队列来说,正在扩容的时候只要确保持有锁,挡住外界的读写操作,就不会有问题。如果你也是这么想的,那么从下面的实现代码中就可以学习到一些优化细节和思路。
privatevoidtryGrow(Object[]array,intoldCap){//解锁操作,这里需要清楚调用这个方法默认是需要保证获得主锁的lock.unlock();//mustreleaseandthenre-acquiremainlockObject[]newArray=null;//对allocationSpinLock进行cas更新,调用的地方是用while包住的,所以没有进入这个if的话还会自旋if(allocationSpinLock==0&&UNSAFE.compareAndSwapInt(this,allocationSpinLockOffset,0,1)){try{//扩大的容量计算intnewCap=oldCap+((oldCap<64)?(oldCap+2)://growfasterifsmall(oldCap>>1));//MAX_ARRAY_SIZE=Integer.MAX_VALUE-8//oldCap最大就能到MAX_ARRAY_SIZE,如果计算出来的newCap大于MAX_ARRAY_SIZE,那么就判断一下oldCap+1是不是已经超过了MAX_ARRAY_SIZE,如果超过就抛出OutOfMemoryError异常,也就是说最后一次扩容最大只能到MAX_ARRAY_SIZE的容量,下一次就不行了if(newCap-MAX_ARRAY_SIZE>0){//possibleoverflowintminCap=oldCap+1;if(minCap<0||minCap>MAX_ARRAY_SIZE)thrownewOutOfMemoryError();newCap=MAX_ARRAY_SIZE;}if(newCap>oldCap&&queue==array)//新数组newArray=newObject[newCap];}finally{//设置allocationSpinLock为0放开扩容操作限制allocationSpinLock=0;}}//这个条件成立意味着cas失败或者allocationSpinLock状态为1,表示有线程正在扩容if(newArray==null)//backoffifanotherthreadisallocating//让出CPUThread.yield();lock.lock();if(newArray!=null&&queue==array){queue=newArray;System.arraycopy(array,0,newArray,0,oldCap);}}
扩容操作并没有像其他方法一样上来就抢锁,而是进行了lock.unlock()
操作,再看下去发现它是使用原子cas更新allocationSpinLock
来保证没有其他线程可以并发执行扩容的逻辑代码。这样就优化了在扩容时对其他操作的性能影响。
总结
在清楚了PriorityQueue
数据结构后对于理解PriorityBlockingQueue
的实现机制就很简单了,主要需要理解到ReentrantLock
和Condition
的作用,因为前面已经详细进入过AQS系列的世界,现在看来从基础的开始看起,一些花里胡哨的东西融会贯通也是容易的。
后面和PriorityBlockingQueue
有点关联的是DelayedWorkQueue
和ScheduledThreadPoolExecutor
。路线图大概是这样的:UNSAFE->AQS->ReentrantLock+PriorityQueue->PriorityBlockingQueue->DelayedWorkQueue->ScheduledThreadPoolExecutor
-
JDK源码分析实战系列-PriorityBlockingQueue
前言可以通过分析PriorityBlockingQueue来了解JUC中的线程安全的队列实现的一些套路,这些套路会在JUC中...
来源: -
资讯:Altium Designer v23.0.1.38图文详解
AltiumDesigner(AD)最新安装河蟹教程,ltiumdesigner显著地提高了用户体验和效率,利用时尚界面使设计流...
来源: JDK源码分析实战系列-PriorityBlockingQueue
资讯:Altium Designer v23.0.1.38图文详解
焦点热议:历史总是惊人地相似:复古主机Atari VCS宣告停产 一个时代终结
网友称考研民宿房费暴涨近20倍 店家:每年都一样
中国企业站稳全球LCD市场!李东生:TCL部分技术领先三星
消息!超可爱!《王者荣耀》梦奇赛年皮肤来了 特效贼棒
环球热讯:《王者荣耀》《合金弹头》联动:联名首发新英雄莱西奥
【世界播资讯】高能吸水 洁丽雅纯棉毛巾:15.9元/3条
今日报丨Intel显卡事业部突然解散!掌门人Raja回归首席架构师
全球新消息丨国内油价要止步“三连跌”!元旦后或迎新一轮价格上调
世界微头条丨比iPhone 14 Pro Max还轻 OPPO Find N2明天首销:7999元
Go 快速入门指南 - 环境安装
环球快看:什么是 HTML?
热讯:基础可视化图表之堆叠条形图
环球新动态:window系统增强优化工具
世界今热点:智创万物,数赢未来——如何助推数智时代的发展浪潮
每日时讯!入口脆甜 林家铺子乌龙茶蜜桃罐头19.9元四罐
今日讯!5年了 网易云音乐终于撕下了“网抑云”标签
全球热资讯!羊被冻死牧羊犬贴身供暖试图唤醒 网友:边牧聪明又有情
每日速读!山东一地120和119到路口秒变绿灯 网友:建议全国推广
天天看点:腾讯智能车技术花样用 数万人疯狂点赞转发
世界消息!(笔记)PID算法讲解
低代码:让企业“活”起来,赋能企业数字转型
今日要闻!大四上 | 计算机综合课设答辩经验帖
一、【Java】多线程与高并发
世界热资讯!小米史上最强!雷军确认小米13 Pro支持Wi-Fi 7:国内认证后开放
全球最资讯丨今天突然发现谷歌翻译用不了,发现是谷歌域名解析问题,现提供以下方法解决
快报:高帧畅玩《巫师3》!满血3060游戏本华硕天选3双旦入手7599 性价比超高
天天热头条丨豆瓣评分跌至6.3!《三体》动画播放量破2亿
东西生锈了是什么原因?东西生锈了怎么去除?
cbz是什么文件格式?cbz文件格式怎么打开?
快讯:创元集团的数智化实践 这次选择了和火山引擎 VeDI 搭档
大喜之日是什么意思?大喜之日祝福语
碳化硅是什么材料?碳化硅的用途有哪些?
越南十二生肖是哪些动物?越南十二生肖和中国的区别
newjeans为什么叫吴晓梅?newjeans女团成员个人资料
省略号的快捷键是什么?省略号的快捷输入方式
皮卡全面解禁再下一城!广西南宁:明年起进城无需办通行证
登陆火星4年电量即将耗尽:探测器洞察号发文告别
【新要闻】中国汽车流通协会:建议全面取消汽车限购 买车可抵税
世界百事通!如何在Word表格中拆分或合并单元格?
当前速讯:Kubernetes监控手册02-宿主监控概述
【全球新要闻】STM32 SPI DMA 源码解析及总结
全球快看点丨MySQL-带你上官网看索引
天天简讯:图算法、图数据库在风控场景的应用
热头条丨Redmi K20 Pro钉子户三年多不换机:就等卢伟冰发K60
最强性能旗舰!一加11配置公布:二代骁龙8、直接12GB+256GB起步
速读:QQ音乐iOS版12.0版发布:新增“臻品母带” 无损音质升级
“灵魂”没了!育碧确认《刺客信条:英灵殿》Steam版将无成就系统
天天观速讯丨美版《西游记》剧照公布:吴彦祖悟空、杨紫琼观音亮相
赛尔号动画片的结局是什么?赛尔号动画片精灵实力排名
流浪地球小说结局是什么?流浪地球小说经典语录
二极管如何判断正负极?二极管工作原理
世界快消息!Visual Studio Code 安装教程
Redis集群的三种方式详解(附优缺点及原理区别)
全球即时:echarts设置单位的偏移
每日速看!网约车司机一路刷抖音吓坏女乘客 司机:投诉去吧 无所谓的
天天快资讯:因收购动视暴雪 微软被美国十名玩家集体诉讼
天天视讯!气场百万 比亚迪仰望高端越野车预告:L形尾灯头次见
【独家】OPPO部分旗舰能升级到Android 17:国产手机独此一家
TCP套接字
全球即时:认证管理(锐捷无线篇)
热资讯!基于 Dubbo-Admin 实现根据请求条件路由
最新快讯!教你用Java实现动态调色板
4090也秒怂!东北网友晒NV RTX 3070显卡温度:这效果我服!
大众ID.Xtreme概念车曝光:旗下最野性的电动车
当前快讯:员工漏打卡11次被辞 法院判决:公司赔大发了
“兔圆圆”!2023年总台春晚标识和吉祥物官宣 附春晚节目单
每日速讯:网易MOBA游戏《无尽战区》宣布复活!曾于两年前停运
世界快看点丨Spring Cloud 2022 正式发布!我的天,OpenFeign 要退出历史舞台了?!
焦点快播:君子不玩物丧志,亦常以借物调心,网站集成二次元网页小组件(widget)石蒜模拟器,聊以赏玩
天天播报:让人诧异!浙江台州天上突然飘落大量羽毛:宛如鹅毛大雪
环球热文:美国动物园将归还大熊猫丫丫和乐乐 结束20年租期:曾被质疑虐待国宝
除了蔚来:大多数车企都给黑客赎金了
全球看热讯:韩国刷新世界最低生育率纪录 上学人减半:日本欧洲更慌了
天天速看:性能超RX7900 XTX!RTX 4070/4070 Ti确定:这售价给老黄买单?
焦点速读:世界最慢的PC诞生 单核跑分不到13900K的百分之一
跟着TDP配电源怎么就蓝屏了?原因揭开
环球新消息丨vue-router
每日速讯:i9-13900K史上第一次超到9GHz!液氦、零下250度
今日快讯:核显笔记本也能跑50帧夜之城!AMD这次干的好啊
环球最资讯丨RTX 40笔记本显卡全线泄露:第一次xx90、功耗达175W
【世界快播报】Intel官方“意外”走光6GHz i9-13900KS:基础功耗150W
60万粉丝女网红偷平价睡衣被抓:真相大跌眼镜
全球时讯:《泰坦尼克号》的世纪疑问 卡梅隆终于解答了:杰克和露丝没法一块活下来
2023年北美最受期待的10大电影来了
当前焦点!FreeSWITCH学习笔记:日志
每日聚焦:官方公布长征九号重型火箭!运力150吨、2030年左右首飞
【环球快播报】太阳的“脾气”突然变了!日益活跃起来:科学家们感到紧张
每日看点!央视科普:黄河源头是巴掌大的小泉眼!反差感十足
天天快播:普通人或者门外汉该怎样入门编程?
洛谷 P5401 [CTS 2019] 珍珠 题解
红魔8 Pro拥有最震撼屏占比:边框比iPhone 14 Pro更窄
世界首富也扛不住!特斯拉被曝暂停招聘 下季度新一波裁员
真卖不动了 2022年全球电视出货量仅2.02亿台:创十年新低
当前要闻:12306出现北京直达香港高铁 网友火速围观:官方客服回应
热推荐:北京多地下雪你看到没?62条公交线路临时有变
关注:充电式加热羽绒服突然火了 又一“韭菜收割机”问世?
全球观热点:一日痛失两位院士!稀土冶金专家张国成、激光技术专家赵伊君逝世
快播:只有《流浪地球2》才适合中国观众?《阿凡达2》全球票房一览:国人贡献第二