项目中碰到一个问题,ScheduledExecutorService
实例通过scheduleAtFixedRate
起了一个定时循环的任务,发现这个任务终止了,但是又没有相关日志提示。
本文得出一个结论:
当某次执行该任务,若出现异常且没有try catch,不会打印任务异常日志,并且会终止后续的任务
我们来看下验证过程:
通过Runnable的run方法中抛出一个异常,查看是否继续打印日志,如果是没有日志继续打印,说明异常导致整个计划任务终止了。
捕获并处理异常
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
public class ScheduleExecutorServiceTest {
public static void main(String[] args) {
ScheduleExecutorServiceTest test = new ScheduleExecutorServiceTest();
test.testAtFixedRate();
}
private ScheduledExecutorService executor;
public ScheduleExecutorServiceTest() {
executor = Executors.newScheduledThreadPool(4);
}
public void testAtFixedRate() {
executor.scheduleAtFixedRate(new Runnable() {
public void run() {
System.out.println("执行主任务");
try{
//抛出一个计算异常
long result = 2/0;
}catch (Exception e){
System.out.println(e);
}
}
}, 1000, 3000, TimeUnit.MILLISECONDS);
}}
上文中抛出的异常已经被处理,我们看下结果:
执行主任务
java.lang.ArithmeticException: / by zero
执行主任务
java.lang.ArithmeticException: / by zero
上述结果表明按预期间隔3s打印了执行信息,说明捕获异常后,不影响下一个任务的触发
。
未捕获异常
下面我们模拟下如果不try catch 异常的场景,注释掉上文中的try catch语句:
public void run() {
System.out.println("执行主任务");
// try{
long result = 2/0;
// }catch (Exception e){
// System.out.println(e);
// }
}
}, 1000, 3000, TimeUnit.MILLISECONDS);
我们再看下结果:
执行主任务
日志发现打印的内容只打印了一遍,说明只执行了一次就挂了,后续的任务不再触发;且没有任何异常日志输出。因此,我们格外需要注意,尽量捕获异常,避免没有错误日志,导致无法定位问题。