关于线程:再不解决延迟不当小心你的内存被打爆

37次阅读

共计 838 个字符,预计需要花费 3 分钟才能阅读完成。

摘要: 这是在具体代码中发现的不当提早的问题,极其状况下可能把内存打爆。

本文分享自华为云社区《线程中不当应用提早问题》,原文作者:技术火炬手。

背景

这是在具体代码中发现的不当提早的问题,极其状况下可能把内存打爆。

代码 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 的工作

测试后果:

合乎预期

点击关注,第一工夫理解华为云陈腐技术~

正文完
 0