Timer和TimerTask
Timer是一种线程设施,用于安排以后在后台线程中执行的任务。可安排任务执行一次,或者定期重复执行,可以看成一个定时器,使用的时候会在主线程之外起一个单独的线程执行指定的计划任务,可以指定执行一次或者反复执行多次,可以调度TimerTask。TimerTask是一个抽象类,实现了Runnable接口,所以具备了多线程的能力,代表一个可以被Timer执行的任务。一个Timer调度的例子
import java.util.Timer;
import java.util.TimerTask;
public class TestTimer {
public static void main(String[] args){
System.out.println("About to schedule task");
new Reminder(3);
System.out.println("Task scheduled.");
}
public static class Reminder{
Timer timer;
public Reminder(int sec){
timer=new Timer();
timer.schedule(new TimerTask() {
@Override
public void run() {
System.out.println("Time's up!");
timer.cancel();
}
}, sec*1000);
}
}
}
运行之后,在console会首先看到:
About to schedule task
Task scheduled.
3秒后,会看到
Time’s up!
从这个例子可以看出一个典型的利用timer执行计划任务的过程如下:
- new一个Timer类,Timer的构造函数里会起一个单独的线程来执行计划任务。
- new一个TimerTask的子类,重写run方法来指定具体的任务,在这个例子里,我用匿名内部类的方式来实现了一个TimerTask的子类
再来一个例子:
package com.wj.test;
import java.util.Date;
import java.util.Timer;
import java.util.TimerTask;
public class MyTask extends TimerTask{
private int id;
public MyTask(int id){
this.id=id;
}
@Override
public void run() {
// TODO Auto-generated method stub
System.out.println("线程"+id+"正在执行....");
}
public static void main(String[] args){
Timer timer=new Timer();
//5秒后启动线程1
timer.schedule(new MyTask(1), 5*1000);
//线程2
MyTask myTask=new MyTask(2);
//1s后启动,以后每3秒执行一次
timer.schedule(myTask, 1*1000, 3*1000);
Date date=new Date();
//以date为参数,指定某个时间点执行线程
timer.schedule(new MyTask(3), new Date(date.getTime()+2*1000));
System.out.println("end in main thread...");
}
}
可以看到控制台输出:
end in main thread…
线程2正在执行….
线程3正在执行….
线程2正在执行….
线程1正在执行….
线程2正在执行….
线程2正在执行….
线程2正在执行….
Timer终止的问题:
默认情况下,只要一个程序的timer线程在运行,那么这个程序就会保持运行。可以通过以下3种方法终止一个timer线程:
(1)调用timer的cancle方法。你可以从程序的任何地方调用此方法,甚至在一个timer task的run方法里;
(2)让timer线程成为一个daemon线程(可以在创建timer时使用new Timer(true)达到这个目地),这样当程序只有daemon线程的时候,它就会自动终止运行;
(3)调用System.exit方法,使整个程序(所有线程)终止。