Timer应用与源码
1.Timer介绍
java.util包下提供了对定时任务的支持,在JDK很早的版本就支持了,但是由于一些问题被逐渐淘汰了,现在建议使用ScheduledThreadPoolExecutor来代替Timer
2.Timer使用Demo
/*** @description: 测试Timer* @author:sgy* @date: 2023-08-06*/
public class TimerTest {public static void main(String[] args) {// 可以通过参数指定是否是守护线程Timer timer = new Timer();TimerTask task = new TimerTask() {@Overridepublic void run() {System.out.println("1");}};// 延迟3秒执行timer.schedule(task,3000);// 延迟1秒执行,固定每3秒执行一次timer.schedule(task,1000,3000);// 延迟1秒执行,固定每3秒执行一次,这个方法会修正由于GC或其他原因导致的时间偏差timer.scheduleAtFixedRate(task,1000,3000);}
}
一次性任务相关API
- void schedule(TimerTask task, long delay):延迟delay毫秒后执行一次task
- void schedule(TimerTask task, Date time):在指定时间time执行一次task,如果time过期,将会立即执行
可重复执行任务相关API
- void schedule(TimerTask task, long delay, long period):延迟delay毫秒后执行task,之后每隔period毫秒执行一次task
- void schedule(TimerTask task, Date firstTime, long period):在指定时间time执行一次task,之后每隔period毫秒执行一次task
- void scheduleAtFixedRate(TimerTask task, long delay, long period):延迟delay毫秒后执行task,之后每隔period毫秒执行一次task
- void scheduleAtFixedRate(TimerTask task, Date firstTime, long period):在指定时间time执行一次task,之后每隔period毫秒执行一次task
3.Timer注意点
- 如果firstTime已经过期,但是Timer将会立即开始执行任务,之后按照period间隔重复执行任务
- Timer内部仅维护一个线程,当任一TimerTask抛出异常,将导致此线程终止运行,该Timer负责的所有任务都无法执行
- Timer内部仅维护一个线程执行所有TimerTask,为了避免错误,一个Timer对象最好仅调度一个TimerTask对象,除非可以确保多个TimerTask之间一定不会相互影响
- Timer在创建时实际上是默认在内部维护了一个非守护线程,即使任务全部执行完成,线程也并不会销毁,Timer提供cancel()方法,可以手动调用取消定时器所有的任务,并销毁定时器
- 如果是要取消单个任务,可以使用TimerTask的cancel()方法
- 当TimerTask调用cancel之后,任务是取消了,但Timer自身并不能马上知道TimerTask被取消,而是在准备执行前才知道,因此Timer内部还维护着这个任务的引用。若希望Timer立即清除引用,可调用Timer.purge()立即执行清除