摘要:这是在具体代码中发现的不当提早的问题,极其状况下可能把内存打爆。
本文分享自华为云社区《线程中不当应用提早问题》,原文作者:技术火炬手 。
背景
这是在具体代码中发现的不当提早的问题,极其状况下可能把内存打爆。
代码DevLicenseServiceRoaDelegateImpl.java
定义:
应用:
signalRefreshHelp 定义
这段代码最大问题是应用提早算法不当,在极其状况下会导致内存暴涨,重大影响服务程序的性能。
不要应用sleep来实现提早
应用sleep实现提早看起来十分直观,然而这个在高并发、多申请、长期运行的服务程序里必须特地小心。这是因为掂量服务程序性能的一个十分重要的指标是QPS, 就是服务程序的解决能力,个别状况下越大越好;服务程序的总并发能力等于每个线程的qps;单个线程的QPS = 1000毫秒 / (解决一个申请的毫秒);所以下面那个线程的QPS <= 1000 / 10000 = 0.1 (因为线程sleep了10000毫秒)。
这里的解决逻辑是谬误的!也有很重大的性能隐患,不过幸好调用这个api 申请不多,才没有导致重大问题。
开发者的用意是在创立一个工作后,提早10s执行该工作,解决时序图如下
如果工夫点t1 & t2 挨得很靠近的话,线程在执行job1 & job2 也是很靠近。
但理论的状况变成:
就算创立job1 & job2的工夫很靠近,但job2执行的工夫会比预期多了10s;间断提交的工作越多,越容易沉积,这些沉积的工作寄存在 blocking queue,始终到处理完毕才删除;如果这类申请很多的话,很容易引起内存爆掉。
解决方案
抉择适合的数据结构,默认线程池关联的队列是LinkedBlockingQueue , 没有提早管制,能够应用DelayQueue
DelayQueue外部应用了PriorityQueue 按工夫排序;须要本人应用Delayed 接口封装申请数据
上面是例子
测试代码,同时退出 3个须要提早10s的工作
测试后果:
合乎预期
点击关注,第一工夫理解华为云陈腐技术~