果不其然,通过这个方法的 doc 中下面的这段话,大概可以知道任务遇到异常的时候,这个任务就不再执行。当然其他任务是不受影响的。
If any execution of the task encounters an exception, subsequent executions are suppressed. Otherwise, the task will only terminate via cancellation or termination of the executor. If any execution of this task takes longer than its period, then subsequent executions may start late, but will not concurrently execute. 复盘根据楼主上面的分析过程,可以知道导致出问题的原因就是代码中抛出了非受检异常,下面是楼主的测试代码,代码很简单就是使用 ScheduledExecutorService 启动两个定时任务,其中一个抛出空指针异常线程不捕获。
public class TestCase { public static void main (String[] args) { ScheduledExecutorService service = Executors .newSingleThreadScheduledExecutor(); service.scheduleAtFixedRate(new TestJob(), 0, 1000, TimeUnit.MILLISECONDS); service.scheduleAtFixedRate(new TestJob2(), 0, 1000, TimeUnit.MILLISECONDS); } static class TestJob implements Runnable { int count = 0; public TestJob() { } @Override public void run() { // try { count++; System.out.println("TestJob count : " + count); if (count == 5) { throw new NullPointerException(); } // } catch (Exception e) { // e.printStackTrace(); // } } } static class TestJob2 implements Runnable { int count = 0; public TestJob2() { } @Override public void run() { count++; System.out.println("TestJob2 count : " + count); } } }代码运行结果:在 TestJob 抛出异常后不再执行,TestJob2 不受影响可以继续执行。
问题解决问题产生的根源找到了,解决起来就比较简单了,具体代码如下所示
static class TestJob implements Runnable { int count = 0; public TestJob() { } @Override public void run() { try { count++; System.out.println("TestJob count : " + count); if (count == 5) { throw new NullPointerException(); } } catch (Exception e) { e.printStackTrace(); } } } 小结总的来看这个问题也比较简单,相对来说比较隐蔽一些。当然,跟自己平时编码规范关系很大。