共计 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 的工作
测试后果:
合乎预期
点击关注,第一工夫理解华为云陈腐技术~