在JDK库中Timer类的作用是是负责计划任务的功能,也就是在指定的时间开始执行某一个任务。Timer类的方法列表如下图所示,具体可以参照API说明。
Timer类的主要作用是设置计划任务,但封装任务的类却是TimerTask类(计划任务是调用timer.schedule()方法去执行的,需要执行的任务为第一个参数,也就是TimerTask类)。也就是说,执行计划任务的代码要放在TimerTask的子类中,因为TimerTask是一个抽象类(public abstract class TimerTask implements Runnable)。下面看下schedule方法的介绍。
schedule(TimerTask task, Date time)
该方法的作用是在指定的日期执行一次某个任务,如果设置的时间比当前时间晚,那么到设置的时间再执行任务,如果设置的时间比当前时间早,那么立即执行。下面看下代码示例。
在子类中实现了run方法,并在run方法中输出当前运行时间的字符串形式。这里使用的是一个过时的方法Date.toLocalString()(已过时。 从 JDK 1.1 开始,由DateFormat.format(Date date)取代),虽然过时了但是还能运行就是了,暂时拿来测试。下面看下测试类和结果。
这里的dateByStr是指执行任务的时间,将该时间作为第二个参数传入schedule方法中,这里设置的时间是20:08,控制台输出的当前时间21:29,设置的时间是比当前时间早的,那么调用mt的时间就是马上执行的,从运行结果也可以看到,mt也是马上运行的。下面来看下比当前时间晚的时间的结果。
这里和上面的测试程序是一样的,只是测试的时间换做是未来的时间,这里从结果可以看到,mt是在我们设置的时间运行的。
但是呢,这里有个问题就是,任务虽然执行完了,但是进行还没有销毁,呈红色状态(右下角程序还在运行)。
下面看下创建Timer对象的源码。调用的是无参的构造函数
public Timer() {
this("Timer-" + serialNumber());
}
从这边可以看到调用的是Timer(String name)方法(构造器中this()表示调用形式参数相同的同一个类中的另一个构造器),下面在看下Timer(String name)
public Timer(String name) {
thread.setName(name);
thread.start();
}
这里可以看到,其实每次创建Timer就是启动一个新的线程,这个新启动的线程不是守护线程(守护 线程,是指在程序运行的时候在后台提供一种通用服务的线程,比如垃圾回收线程就是一个很称职的守护者,并且这种线程并不属于程序中不可或缺的部分。因此,当所有的非守护线程结束时,程序也就终止了,同时会杀死进程中的所有守护线程。反过来说,只要任何非守护线程还在运行,程序就不会终止。),它一直在运行。