不知道大家之前听说过定时调度没?如果没有听说过,这里我给大家几个小例子,如在2009-5-6 晚上12点发送一个电子邮件、每隔五分钟向控制台输出当前时间等。这些都是定时调度所涉及到的内容,今天我就给大家讲解下Java平台本身自带的定时调度类。这就是Timer和TimerTask,顾名思义,Timer为定时器而TimerTask则为定时任务。
在一般的情况下,我们也可以用Thread来实现一个定时调度的任务系统,如启动一个后台线程,然后里面的run方法是一个while(true)结构,接着使用Thread的sleep方法来定时休眠,就可以实现。不过对于定时任务,Java中已经提供了Timer类来帮助我们完成这个事情。
在进行讲解之前,首先给出个例子:
public class MainClass {
public static void main(String[] args) {
Timer timer = new Timer();
timer.schedule(new DisplayQuestionTask(), 0, 10 * 1000);
try {
Thread.sleep(10000);
} catch (InterruptedException e) {
}
timer.cancel();
}
}
class DisplayQuestionTask extends TimerTask {
int counter = 0;
public void run() {
System.out.println(counter++);
}
}
执行上述代码的时候,大家可以看到,控制台并没有立即返回,而是等待了10秒才结束执行;并且在控制台里也输出了0,1两个数字。我想稍微的给大家讲解下这个代码。在main方法中,我们首先定义了一个Timer类,该类用于在后续代码中进行具体的时间调度,即每隔多少时间进行调度,调度是通过schedule方法来实现的,该方法有很多多态方法,给大家列举下:
void schedule(TimerTask task, Date time) //安排在指定的时间执行指定的任务。
void schedule(TimerTask task, Date firstTime, long period) //安排指定的任务在指定的时间开始进行重复的固定延迟执行。
void schedule(TimerTask task, long delay) // 安排在指定延迟后执行指定的任务。
void schedule(TimerTask task, long delay, long period) //安排指定的任务从指定的延迟后开始进行重复的固定延迟执行。
从上面的代码可以看出,可以在指定时间执行、可以在指定时间开始执行然后每隔固定时间循环执行、在固定延迟后执行一次调度、在固定延迟后执行一次然后每隔固定时间循环执行。我们上面的代码用的显然是第四种方式,在方法调用后的0秒后执行一次然后每隔10秒执行一次。这里注意下,Thread.sleep(10000);它的主要作用是防止主线程提前退出,给出一个修改后的代码,大家自己运行下:
public class MainClass {
public static void main(String[] args) {
Timer timer = new Timer();
timer.schedule(new DisplayQuestionTask(), 0, 10 * 1000);
/*try {
Thread.sleep(10000);
} catch (InterruptedException e) {
}*/
timer.cancel();
}
}
class DisplayQuestionTask extends TimerTask {
int counter = 0;
public void run() {
System.out.println(counter++);
}
}
该代码与开始的代码的主要差别是,我将Thread.sleep(10000)注释掉了。大家执行后可以看出,代码会立即返回,控制台也没有任何输出。这里的主要原因是主线程没有等待,直接退出,导致程序退出。
这里稍微注意下,在Java应用中,只有主线程存在,其他的线程才能够存在;如果主线程退出了,那么程序就结束了。
然后在最后的语句中,我们调用了Timer的cancel方法,该方法的主要作用是终止计时器,并将所有的任务都放弃。
了解了这么多,给大家一个比较有用的调度任务,它调用了Java的垃圾收集器,用于定时进行垃圾回收,直接见代码:
public class MainClass {
public static void main(String[] args) {
Timer timer = new Timer();
GCTask task = new GCTask();
timer.schedule(task, 5000, 5000);
while (true) {
try {
Thread.sleep(500);
} catch (InterruptedException e) {
}
}
}
}
class GCTask extends TimerTask {
public void run() {
System.out.println("Running the scheduled task...");
System.gc();
}
}
大家在执行本代码后,会发现控制台一直不返回,这个主要是通过while(true)实现的。然后在控制台上大家可以看到我们定义的输出。上面的代码完成的是每隔5秒执行一次垃圾回收,回收没在用的内存。注意,该代码只是要求Java垃圾回收器来回收内存,但并不是调用后Java垃圾收集器就会回收内存。
同时有一点没有提到,所有的定时任务都是继承自TimerTask,大家在使用的时候稍微注意点。
OK,学了今天的知识相信大家可以用Timer来完成自己需要的任务了。有一点,如果能让计算机去做的,尽量不要用人来做了,O(∩_∩)O哈哈~。充分发挥自己的想象力。顺便提一下,在开源领域有一个更为强大的调度框架,名字是QuartZ,有机会会给大家讲解。