【线程池】ScheduledThreadPool异常处理

背景

某个任务类负责定时处理一些抽取数据的逻辑,通过定时线程池来实现。

问题

这天发现数据没有被处理,初步检查后定位到是因为放到线程池的这个任务并没有执行,而其他任务却可以正常地执行。

分析

梳理该任务的代码逻辑,其中因为在处理数据的过程中遗漏了对数据的合规校验,而正是因为这次残缺的数据而导致代码抛出异常。

通过查找资料和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任务抛出异常后,线程池不会再进行调用

你可能感兴趣的:(#,并发编程)