Thread Starvation导致测试用例随机失败

项目迁移后,一个测试用例出现随机失败,原因是ForkJoinPool.commonPool只有一个线程,导致线程饥饿(Thread Starvation)。线程池大小由CPU核数决定,当超时任务占用线程时,短耗时任务无法及时执行。解决方案包括增加硬件资源或调整测试用例,确保短任务优先执行。问题关键在于提交给CompletionService的任务顺序不定,通过修改为TreeSet并定制比较器确保正确顺序。

问题描述

项目迁移到新的平台上后,已有的一个测试用例出现随机的失败,在老的平台上,已经运行了大半年,都是好好的,本地也是运行的好好的,very trick~~~.

没有办法,只能撸代码了。我们有一个功能,需要从不同的sever抓取数据,然后把数据聚合到map里面。为了加快响应速度,引入了线程池,代码如下:

// 查询后台可用的server列表
Set<Server> servers = this.serverService.getServers();

Executor executor = new DelegatingSecurityContextExecutor(ForkJoinPool.commonPool()); 
CompletionService<Object> completionService = new ExecutorCompletionService<>(executor);
// 提交task给completionService
servers.forEach(server -> completionService.submit(() -> this.doSearch(server));

// 获取结果,每次最大等待20s
for (int i = 0; i < servers.size(); i++) {
    Future<Object> future = completionService.poll(20, TimeUnit.SECONDS);
    if (!(future == null || future.isCancelled())) {
            // 从future中获取结果
    }
}

在单元测试用例中,设计了如下测试场景:mock 两个severs(server1, server2), 并且让server2在30s后才返回结果

 //Server2 with 30s delay
BDDMockito.doAnswer(AdditionalAnswers.answersWithDelay(3000
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值