一 Timer 介绍
在开发中我们经常会遇到一些简单定时任务的需求,而不需要量级较重的定时任务就可以采取java定时器;
java.util.Timer工具类中的Timer 是定时器,但定时任务写在java.util.TimerTask 中,由 Timer 执行 TimerTask ;
Timer 的本质就是线程,构造方法如下
public
从源码角度可知,如果这样创建定时器非守护线程,即使主线程运行结束,定时任务还是会执行;如果我们会使用如下的构造方式创建定时任务就是守护线程方式,会随着主线程的消亡而消亡;
public
Timer内部维护了一个优先队列,用于顺序执行TimerTask任务;
private
优先队列的实现就是数组方式作为平衡二叉堆
private
TimerTask 实现了Runnable 接口,执行的任务动作就是run方法;
public
所以定时器的本质就是启动了一个新的线程执行任务,这些任务都会维护在优先队列里面;
timer的调度主要方法如下
- schedule(TimerTask task, long delay) 延迟 delay 毫秒执行一次
- schedule(TimerTask task, Date time) 指定时间执行一次
- schedule(TimerTask task, long delay, long period) 延迟delay毫秒以后,每隔period毫秒执行一次
- schedule(TimerTask task, Date firstTime, long period) 从firstTime时刻开始,每隔period毫秒执行一次
二 Timer使用示例
如果方式简单使用Timer去延迟执行线程任务,当然其它四种方法同理,调用方式区别不大;
public
输出的间隔大约就是5秒
程序执行时间 18:47:28.258
线程执行了18:47:33.259
三 cancel 方法
TimerTask的cancel () 方法是将自身任务从任务队列中移除
我们先延迟2秒,再每2秒执行一次看效果
public
结果是每2秒会执行一次
程序执行时间18:59:23.557
线程执行了18:59:25.558
线程执行了18:59:27.558
线程执行了18:59:29.559
启用cancel方法,后 就只会执行一次
public
输出如下
程序执行时间19:02:12.770
线程执行了19:02:14.772
Timer的cancel方法是移除所有的任务;
public
输出直接报错
程序执行时间:19:34.294
Exception in thread "main" java.lang.IllegalStateException: Timer already cancelled.at java.util.Timer.sched(Timer.java:397)at java.util.Timer.schedule(Timer.java:248)at com.youku1327.base.timer.TimerAbsolute.main(TimerAbsolute.java:28)
四 scheduleAtFixedRate
schedule 与 scheduleAtFixedRate 方法的区别如下:
schedule 方法如果执行任务的时间没有被延迟,下一次执行任务时间参考的是上一次任务执行的开始时间
scheduleAtFixedRate 方法如果执行任务的时间没有被延迟,下一次执行任务时间参考的是上一次任务执行的结束时间
五 Timer缺点
- Timer 对调度的支持是基于绝对时间的,而不是相对时间,所以它对系统时间的改变非常敏感。
- Timer 线程是不会捕获异常的,如果 TimerTask 抛出的了未检查异常则会导致 Timer 线程终止。