Java 定时任务

定时任务就是在指定时间执行程序,或周期性执行计划任务。Java中实现定时任务的方法有不少,本文从从JDK自带的一些方法来实现定时任务的需求。

Timer和TimerTask

  • schedule和scheduleAtFixedRate函数都是阻塞式的,若是定时任务的执行时间大于定时任务的定时周期,则下个周期的定时任务会在前个周期的任务完成后才会启动。
  • 定时任务是单线程的,同一时间只能执行一个定时任务
  • 执行定时任务时,如出现一个未捕获异常致使任务退出,那下个周期的定时任务也不会启动,因此定时任务必定要用try catch。
public class JavaTimeTest {

    private final static Logger logger = Logger.getLogger("JavaTimeTest");
    public JavaTimeTest() {
    }

    public static void main(String[] args) {
        class Test1 extends TimerTask {
            @Override
            public void run() {
                logger.info("begin running=========");
                try {
                    Thread.sleep(3000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                logger.info("end running=========");
            }
        }
        new Timer().scheduleAtFixedRate(new Test1(), 0, 1000);
    }
}
测试结果:
十一月 15, 2016 9:40:11 下午 com.zzl.JavaTimeTest run
信息: begin running=========
十一月 15, 2016 9:40:14 下午 com.zzl.JavaTimeTest run
信息: end running=========
十一月 15, 2016 9:40:14 下午 com.zzl.JavaTimeTest run
信息: begin running=========
十一月 15, 2016 9:40:17 下午 com.zzl.JavaTimeTest run
信息: end running=========
十一月 15, 2016 9:40:17 下午 com.zzl.JavaTimeTest run
信息: begin running=========
十一月 15, 2016 9:40:20 下午 com.zzl.JavaTimeTest run
信息: end running=========
十一月 15, 2016 9:40:20 下午 com.zzl.JavaTimeTest run
信息: begin running=========

###ScheduledExecutorServiceide

  • Timer对调度的支持是基于绝对时间,而不是相对时间的,由此任务对系统时钟的改变是敏感的;ScheduledThreadExecutor只支持相对时间。
  • 若是TimerTask抛出未检查的异常,Timer将会产生没法预料的行为。Timer线程并不捕获异常,因此 TimerTask抛出的未检查的异常会终止timer线程。此时,已经被安排但还没有执行的TimerTask永远不会再执行了,新的任务也不能被调度了。 ####缺点:依然是阻塞式的方式,若是定时任务的执行时间大于执行周期,下一次定时任务须要在前一次定时任务执行完毕以后才能执行。
public class ScheduleTimerTest {
    private final static Log log = LogFactory.getLog(ScheduleTimerTest.class);

    public ScheduleTimerTest() {
    }

    public static void main(String[] args) {
        class Test1 extends TimerTask {
            @Override
            public void run() {
                log.info("begin running=========");
                try {
                    Thread.sleep(3000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                log.info("end running=========");
            }
        }
        //注意:直接将Test1做为scheduleWithFixedDelay的参数,定时任务仍是会要在上次任务运行完以后才执行下次任务
        //所以,如今定时任务只是每分钟建立一个任务,真正的任务执行是在新建的线程中再执行
        ScheduledExecutorService executor = Executors
                .newScheduledThreadPool(10);
        executor.scheduleWithFixedDelay(
                new Test1(),
                0,  //delay
                1, //频率
                TimeUnit.SECONDS);
    }
}
测试结果:
十一月 15, 2016 9:50:28 下午 com.zzl.ScheduleTimerTest run
信息: begin running=========
十一月 15, 2016 9:50:31 下午 com.zzl.ScheduleTimerTest run
信息: end running=========
十一月 15, 2016 9:50:32 下午 com.zzl.ScheduleTimerTest run
信息: begin running=========
十一月 15, 2016 9:50:35 下午 com.zzl.ScheduleTimerTest run
信息: end running=========
十一月 15, 2016 9:50:36 下午 com.zzl.ScheduleTimerTest run
信息: begin running=========
十一月 15, 2016 9:50:39 下午 com.zzl.ScheduleTimerTest run
信息: end running=========
十一月 15, 2016 9:50:40 下午 com.zzl.ScheduleTimerTest run
信息: begin running=========
相关文章
相关标签/搜索