线程中不当使用延迟问题

举报
技术火炬手 发表于 2021/05/25 19:18:46 2021/05/25
【摘要】 这是在具体代码中发现的不当延迟的问题,极端情况下可能把内存打爆。

背景

这是在具体代码中发现的不当延迟的问题,极端情况下可能把内存打爆。

代码DevLicenseServiceRoaDelegateImpl.java

定义:

image002.jpg

使用:

image004.jpg

signalRefreshHelp 定义

image006.jpg

这段代码最大问题是使用延迟算法不当,在极端情况下会导致内存暴涨,严重影响服务程序的性能。

不要使用sleep来实现延迟

使用sleep实现延迟看起来非常直观,但是这个在高并发、多请求、长期运行的服务程序里必须特别小心。

这是因为衡量服务程序性能的一个非常重要的指标是QPS, 就是服务程序的处理能力,一般情况下越大越好;

服务程序的总并发能力等于每个线程的qps;单个线程的QPS = 1000毫秒 / (处理一个请求的毫秒)

所以上面那个线程的QPS <= 1000 / 10000 = 0.1 (因为线程sleep10000毫秒)

这里的处理逻辑是错误的!也有很严重的性能隐患,不过幸好调用这个api 请求不多,才没有导致严重问题。

开发者的意图是在创建一个任务后,延迟10s执行该任务,处理时序图如下

image008.jpg

假如时间点t1 & t2 挨得很接近的话,线程在执行job1 & job2 也是很接近。

但实际的情况变成:

image010.jpg

就算创建job1 & job2的时间很接近,但job2执行的时间会比预期多了10s;连续提交的任务越多,越容易堆积,这些堆积的任务存放在 blocking queue,一直到处理完毕才删除;如果这类请求很多的话,很容易引起内存爆掉。

解决方案

选择合适的数据结构,默认线程池关联的队列是LinkedBlockingQueue , 没有延迟控制,可以使用DelayQueue

image012.jpg

DelayQueue内部使用了PriorityQueue 按时间排序;需要自己使用Delayed 接口封装请求数据

下面是例子

image014.jpg

测试代码,同时加入 3个需要延迟10s的任务

image016.jpg

测试结果:

image018.jpg

符合预期

【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。