纠纷奇闻作文社交美文家庭
聚热点
家庭城市
爱好生活
创业男女
能力餐饮
美文职业
心理周易
母婴奇趣
两性技能
社交传统
新闻范文
工作个人
思考社会
作文职场
家居中考
兴趣安全
解密魅力
奇闻笑话
写作笔记
阅读企业
饮食时事
纠纷案例
初中历史
说说童话
乐趣治疗

while循环导致的CPU暴涨问题优化实践

11月7日 温柔冢投稿
  最近接到TL分配的新任务,维护一个之前的新应用,在开发新需求的同时,不免也需要排查一些前人代码中埋下的坑。这不最近就出现了线上环境服务CPU较高的情况,让我们一起来围观下怎么对CPU过高问题进行分析以及解决的。优化过程背景
  说明:由于是公司线上业务,这里的业务说明以及代码都进行了脱敏处理。
  线上出现服务CPU占用过高的问题,于是小枫使用top命令定位到CPU比较高的进程ID,再结合jstack命令,导出CPU高的进程的线程信息,定位到问题代码(如何进行线上问题排查不是本文的重点,这里一笔带过,后面再写专门的文章来进行重点阐述)。
  首先说一下业务背景,这段问题代码是从MQ中获取信息并放在队列中进行缓存,在通过单独的线程从队列中获取到数据进行后的业务处理。小枫发现,这段代码中使用了while循环不断从队列中获取数据,判断取出来的map是否为空,不为空进行后面的业务处理,为空的话就继续获取数据。表面上看似乎没有什么问题。但是小枫发现有数据的时候还好,反正就是不断执行业务,但是如果队列中没有数据的话,由于在while循环中,程序依据在不断执行判断,有点CPU空转的意思了。那么该怎么解决问题呢?
  本地测试时未运行while循环时的CPU利用率:
  本地测试时运行while循环后的CPU利用率:
  优化思路
  这段代码的问题就在于队列中没有数据的时候还是不断获取并执行判断,浪费了计算机的CPU资源。这个时候小枫灵光一现,前段时间不是看过LinkedBlockingQueue的源码嘛,其中的take方法实现的是在队列中没有数据的时候进行阻塞,避免一直循环判断,当队列中有数据的时候再唤醒之前阻塞的线程进行后续的数据获取。那么在此处我们可不可以借助于take方法的思想,使用阻塞唤醒的方式来解决这个while循环空转的问题呢?一想到这里,小枫有些激动,仿佛看到了曙光,立马搓了搓自己的双手,准备开始编码测试。优化实现
  原先的while循环代码如下所示:publicstaticclassTakeDataThreadextendsThread{Overridepublicvoidrun(){循环获取数据while(true){MapString,StringmapQueueData。getRecordList(1,2L);如果map一直为空,则一直获取判断,造成CPU空转if(CollectionUtils。isEmpty(map)){System。out。println(continue);}System。out。println(nextstep);}}}publicstaticclassQueueData{privatestaticvolatileLinkedBlockingQueueMaprecordInfoQpublicstaticMapString,StringgetRecordList(intsize,Longtimeout){if(Objects。isNull(recordInfoQueue)){returnCollections。emptyMap();}returnrecordInfoQueue。poll();}}
  优化实现
  1、在getRecordList方法中增加阻塞处理,当队列为空以及获取的map为空时,进行阻塞。publicstaticclassQueueData{privatestaticvolatileLinkedBlockingQueueMaprecordInfoQprivatefinalstaticReentrantLockhandleLocknewReentrantLock();privatefinalstaticConditionnotEmptyhandleLock。newCondition();。。。publicstaticMapString,StringgetRecordList(intsize,Longtimeout){MapString,Stry{handleLock。lockInterruptibly();队列为空进行阻塞while(recordInfoQueuenullCollectionUtils。isEmpty(recordInfoQueue。poll())){notEmpty。await();}}catch(InterruptedExceptione){e。printStackTrace();}finally{handleLock。unlock();}}。。。}
  2、在进行队列初始化以及网队列中缓存数据的时候进行线程唤醒。publicstaticclassQueueData{。。。publicstaticvoidputRecord(MapalarmVo)throwsInterruptedException{if(recordInfoQueuenull){synchronized(QueueData。class){if(recordInfoQueuenull){recordInfoQueuenewLinkedBlockingQueue(10000);}}}recordInfoQueue。put(alarmVo);队列创建以及缓存数据的时候,唤醒线程signalNotEmpty();}privatestaticvoidsignalNotEmpty(){finalReentrantLocktakeLockQueueData。handleLtakeLock。lock();try{notEmpty。signal();}finally{takeLock。unlock();}}。。。}
  调试代码
  本地进行代码调试:publicclassTestMain{publicstaticvoidmain(String〔〕args)throwsIOException,InterruptedException{System。out。println(takeDataThreadstart);TakeDataThreadtakeDataThreadnewTakeDataThread();takeDataThread。start();System。out。println(takeDataThreadend);System。out。println(dataNotifyThreadstart);DataNotifyThreaddataNotifyThreadnewDataNotifyThread(0);dataNotifyThread。start();System。out。println(dataNotifyThreadend);System。out。println(dataNotifyThread2start);DataNotifyThreaddataNotifyThread2newDataNotifyThread(1);dataNotifyThread2。start();System。out。println(dataNotifyThread2end);}。。。}
  在main主线程中执行TakeDataThread的启动
  切换到TakeDataThread
  由于队列没有进行初始化为null,所以此处线程进行阻塞处理。
  TakeDataThread线程的状态由RUNNING转为WAIT
  切换到主线程继续往下执行后面的代码
  主线程中执行DataNotifyThread线程的启动
  切换到DataNotifyThread线程,初始化队列后,原先阻塞的TakeDataThread被唤醒,线程状态由WAIT转变为RUNNING
  至此,小枫完成了将while循环转化为阻塞唤醒的模式,大大降低了服务在进行循环判断时候的CPU使用率。总结
  经过了上述的代码优化过程,终于解决了处理数据的线程CPU过高的问题,小枫将服务中存在类似循环问题的都进行了修改,经过测试服务对应的CPU使用率有了明显的下降,小枫松了口气,终于可以下班了,想着回家一定给自己加个鸡腿补一补伤掉的脑细胞。故事还会继续,他还会遇到怎样的技术挑战,请大家敬请期待。
投诉 评论 转载

丰田将首先在混合动力车型中应用固态电池可缩短充电时间提升续航IT之家12月3日消息,丰田暗示,在将该技术引入电动汽车之前,将首先在其混合动力汽车上部署固态电池。IT之家了解到,混合动力车将继续在丰田公司的电气化战略中发挥核心作用,……特斯拉推出儿童电动车最高时速16公里,售价1900美元北京时间12月2日下午消息,特斯拉在其网上商店推出了一款儿童车(CyberquadForKids),售价为1900美元(约12103元人民币),最高时速为10英里(约16。09……马斯克确认特斯拉电动皮卡将配备矩形方向盘北京时间12月2日消息,据报道,特斯拉首席执行官埃隆马斯克最近证实,该公司备受期待的电动皮卡Cybertruck将配备ModelSX同款矩形方向盘。马斯克在推文中将Cyb……2021智博会丨金山科技RC100零接触检查解疫情之急智慧盛宴来了!8月23日,为期3天的2021中国国际智能产业博览会(以下简称智博会)在重庆正式开幕。本届智博会以智能化:为经济赋能,为生活添彩为主题,吸引了31个国家和地区的6……国轩高科能量密度达到302Whkg单体高镍三元电池已批量试制12月1日,国轩高科在投资者互动平台表示,在磷酸铁锂电池产品方面,目前公司电芯单体能量密度已突破210Whkg,系统能量密度已达160Whkg。在高镍三元电池产品方面,承担的科……电动汽车车主悲催的假期,终于结束了划重点:1、排队4个小时充电1个小时车主的经历折射的恰恰是新能源汽车的补能瓶颈,其背后的明显问题是:充电桩的建设速度远远未跟上汽车的销量速度。2、高速服务区为何不布……while循环导致的CPU暴涨问题优化实践最近接到TL分配的新任务,维护一个之前的新应用,在开发新需求的同时,不免也需要排查一些前人代码中埋下的坑。这不最近就出现了线上环境服务CPU较高的情况,让我们一起来围观下怎么对……11家品牌扎堆北京合生汇,新能源车企上演争夺战曾经4S店的人很难想象,如今的商场,竟然会成为购买汽车的第一入口在北京朝阳区的合生汇中,新能源品牌抢夺战一触即发。新浪科技实际走访发现,截至目前,这家商场总共聚集了11家……FF获法国巴黎银行能源转型基金投资4000万美金IT之家8月30日消息FaradayFuture(简称FF)提交给美国证券交易委员会(SEC)的文件显示,法国巴黎银行能源转型基金代表法国巴黎资产管理公司向FF投资4000万美……外来引种树木诱发我国本土害虫暴发近日,中国林科院森林生态环境与自然保护研究所王小艺团队揭示了区域性害虫在原产地和入侵地暴发成灾的原因。相关论文发表于《生态学杂志》。通过对原产地和入侵地100多年的历史资……基于Vue3和TypeScript项目大量实践后的思考概述Vue3出来已经有一段时间了,在团队中,也进行了大量的业务实践,也有了一些自己的思考。总的来说,Vue3无论是在底层的原理上,还是在业务的实际开发中,都有了长足……社群运营这就是社群带给你的10个价值点作者:小蚱蜢简介:8年互联网营销实战经验,乐于为大家分享实战经验。寻找互联网营销同行交流经验提升自我。精力有限,不卖课程,不付费学习,单纯以互联网交流为主,所有文章纯属本……
每日好价达尔优无线键盘169元罗技套装优惠精致小型SUV,家用代步两相宜,起步价只有7。28万广西走出两个富豪,一个是李宁,另一个是重庆首富,财富达170能源危机暂时缓解欧洲煤炭期货腰斩跌破100美元关键价位DIY一个60000毫安的超级充电宝,这下子够用了2021上半年度20003000元热门机型详细对比测评Red名门修谱家谱记载,建议应详今略古,对吗?线上盲盒app开发起源以及盲盒app开发的发展趋势怎么样?抗日战争中我国军备紧缺,为何不敢捡日军的弹药?全是鲜血换来的不支持5G的手机,现在还值得买吗?直播行业污秽横流,国家何时对臭鱼烂虾动手?降价15,微软宣布HoloLens2开启限时促销
颓废过后的颓废东京奥运会女排各项技术排名,中国女排4人上榜,李盈莹独占两项赠斥丘令冯文罴诗家用空调怎么清洗家用空调清洗方法详解如果收到违章停车告知单怎么处理?实用小技巧男女最渴望的种调情方法为什么林语堂说“西方的艺术来自于女人,中国的艺术来自于山水”工作狂老爸如何将百度账户的点击量转化为咨询量钯金价格今日价格走势小学生作文我们这个班五个正被淘汰的网页设计趋势

友情链接:中准网聚热点快百科快传网快生活快软网快好知文好找美丽时装彩妆资讯历史明星乐活安卓数码常识驾车健康苹果问答网络发型电视车载室内电影游戏科学音乐整形