背景
某个任务类负责定时处理一些抽取数据的逻辑,通过定时线程池来实现。
问题
这天发现数据没有被处理,初步检查后定位到是因为放到线程池的这个任务并没有执行,而其他任务却可以正常地执行。
分析
梳理该任务的代码逻辑,其中因为在处理数据的过程中遗漏了对数据的合规校验,而正是因为这次残缺的数据而导致代码抛出异常。
通过查找资料和demo测试,发现ScheduledThreadPool
这个定时线程池对抛出异常的任务会进行挂起,此后不会再进行调用。
解决
在任务中对任务进行合规校验
可对不可避免的异常进行捕获,避免异常被抛到任务外
测试
public class ScheduledThreadPoolTest {
public static void main(String[] args) {
ScheduledExecutorService scheduledExecutorService = Executors.newScheduledThreadPool(3);
scheduledExecutorService.scheduleAtFixedRate(() -> System.out.println("A"), 0, 2, TimeUnit.SECONDS);
scheduledExecutorService.scheduleAtFixedRate(() -> {
System.out.println("B");
throw new RuntimeException();
}, 0, 2, TimeUnit.SECONDS);
scheduledExecutorService.scheduleAtFixedRate(() -> System.out.println("C"), 0, 2, TimeUnit.SECONDS);
}
}
运行结果
A
B
C
A
C
A
C
...
这里可以看到B任务抛出异常后,线程池不会再进行调用