使用ScheduledThreadPoolExecutor须要注意的问题

玩过linux系统的同窗,应该都知道cron是一个linux下的定时执行工具,一些重要的任务的定时执行能够经过cron来实现,例如天天凌晨1点备份数据等。在JAVA WEB开发中,咱们也常常须要用到定时执行任务的功能,JDK提供了Timer类与ScheduledThreadPoolExecutor类实现这个定时功能。但在使用这两个类的时候,要特别注意异常处理问题。如下是一个模拟程序:java

public class ScheduledThreadPoolExecutorTest {
    public static void main(String[] args) {
        ScheduledExecutorService executorService = new ScheduledThreadPoolExecutor(1);
        BusinessTask task = new BusinessTask();
        //1秒后开始执行任务,之后每隔2秒执行一次
        executorService.scheduleWithFixedDelay(task, 1000, 2000,TimeUnit.MILLISECONDS);
    }

    private static class BusinessTask implements Runnable{
        @Override
        public void run() { 
            System.out.println("任务开始...");
            //doBusiness();
            System.out.println("任务结束...");
        }
    }
}

程序输出结果跟相像中同样:linux

任务开始...
任务结束...
任务开始...
任务结束...ide

但是执行了一段时间后,发现定时任务再也不执行了,去查看后台打印的日志,原来在doBusiness()方法中抛出了异常。为何doBusiness()抛出异常就会停止定时任务的执行呢?去查看JDK的ScheduledThreadPoolExecutor.scheduleWithFixedDelay(Runnable command,long initialDelay,long delay,TimeUnit unit)的方法说明:工具

Creates and executes a periodic action that becomes enabled first after the given initial delay, and subsequently with the given delay between the termination of one execution and the commencement of the next. 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.学习

这段话翻译成中文是:网站

建立并执行一个在给定初始延迟后首次启用的按期操做,随后,在每一次执行终止和下一次执行开始之间都存在给定的延迟。若是任务的任一执行遇到异常,就会取消后续执行。不然,只能经过执行程序的取消或终止方法来终止该任务。翻译

看到这里,咱们明白了缘由,这样就须要把doBusiness()方法的全部可能异常捕获,才能保证定时任务继续执行。把代码改为这样:日志

public class ScheduledThreadPoolExecutorTest {
    public static void main(String[] args) {
        ScheduledExecutorService executorService = new ScheduledThreadPoolExecutor(1);
        BusinessTask task = new BusinessTask();
        //1秒后开始执行任务,之后每隔2秒执行一次
        executorService.scheduleWithFixedDelay(task, 1000, 2000,TimeUnit.MILLISECONDS);
    }

    private static class BusinessTask implements Runnable{
        @Override
        public void run() { 
            //捕获全部的异常,保证定时任务可以继续执行
            try{
                System.out.println("任务开始...");
                //doBusiness();
                System.out.println("任务结束...");
            }catch (Throwable e) {
                // donothing
            }
        }
    }
}

其实,在JAVAWEB开发中,执行定时任务有一个更好的选择:Quartzcode

这个开源库提供了丰富的做业调度集,有兴趣的同窗能够到官方网站中学习一下其用法。开发

相关文章
相关标签/搜索