摘要:但在使用这两个类的时候,要特别注意异常处理问题。否则,只能通过执行程序的取消或终止方法来终止该任务。看到这里,我们明白了原因,这样就需要把方法的所有可能异常捕获,才能保证定时任务继续执行。
玩过linux系统的同学,应该都知道cron是一个linux下的定时执行工具,一些重要的任务的定时执行可以通过cron来实现,例如每天凌晨1点备份数据等。在JAVA WEB开发中,我们也经常需要用到定时执行任务的功能,JDK提供了Timer类与ScheduledThreadPoolExecutor类实现这个定时功能。但在使用这两个类的时候,要特别注意异常处理问题。以下是一个模拟程序:
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("任务结束..."); } } }
程序输出结果跟相像中一样:
任务开始...
任务结束...
任务开始...
任务结束...
可是执行了一段时间后,发现定时任务不再执行了,去查看后台打印的日志,原来在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开发中,执行定时任务有一个更好的选择:Quartz
这个开源库提供了丰富的作业调度集,有兴趣的同学可以到官方网站中学习一下其用法。
文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。
转载请注明本文地址:https://www.ucloud.cn/yun/64025.html
摘要:该方法传入表示如果当前任务正在执行,那么立即终止其执行传入表示如果当前方法正在执行,那么等待其执行完成之后再取消当前任务。 本文主要分为两个部分,第一部分首先会对ScheduledThreadPoolExecutor进行简单的介绍,并且会介绍其主要API的使用方式,然后介绍了其使用时的注意点,第二部分则主要对ScheduledThreadPoolExecutor的实现细节...
摘要:该方法传入表示如果当前任务正在执行,那么立即终止其执行传入表示如果当前方法正在执行,那么等待其执行完成之后再取消当前任务。 本文主要分为两个部分,第一部分首先会对ScheduledThreadPoolExecutor进行简单的介绍,并且会介绍其主要API的使用方式,然后介绍了其使用时的注意点,第二部分则主要对ScheduledThreadPoolExecutor的实现细节...
摘要:该方法传入表示如果当前任务正在执行,那么立即终止其执行传入表示如果当前方法正在执行,那么等待其执行完成之后再取消当前任务。 本文主要分为两个部分,第一部分首先会对ScheduledThreadPoolExecutor进行简单的介绍,并且会介绍其主要API的使用方式,然后介绍了其使用时的注意点,第二部分则主要对ScheduledThreadPoolExecutor的实现细节...
摘要:当面试官问线程池时,你应该知道些什么一执行流程与不同,向中提交任务的时候,任务被包装成对象加入延迟队列并启动一个线程。当我们创建出一个调度线程池以后,就可以开始提交任务了。 最近新接手的项目里大量使用了ScheduledThreadPoolExecutor类去执行一些定时任务,之前一直没有机会研究这个类的源码,这次趁着机会好好研读一下。 原文地址:http://www.jianshu....
摘要:当面试官问线程池时,你应该知道些什么一执行流程与不同,向中提交任务的时候,任务被包装成对象加入延迟队列并启动一个线程。当我们创建出一个调度线程池以后,就可以开始提交任务了。 最近新接手的项目里大量使用了ScheduledThreadPoolExecutor类去执行一些定时任务,之前一直没有机会研究这个类的源码,这次趁着机会好好研读一下。 原文地址:http://www.jianshu....
阅读 2988·2023-04-25 21:23
阅读 3020·2021-09-22 15:24
阅读 861·2019-08-30 12:55
阅读 2094·2019-08-29 18:42
阅读 2606·2019-08-29 16:27
阅读 942·2019-08-26 17:40
阅读 2172·2019-08-26 13:29
阅读 2603·2019-08-26 11:45