定时器是一个应用十分广泛的线程工具,可用于调度多个定时任务以后台线程的方式执行。
在Java中,可以通过Timer和TimerTask类来实现定义调度的功能
1 Timer
java.lang.Object
|--- java.util.Timer
public class Timer extends Object
一种工具,线程用其安排以后在后台线程中执行的任务。可安排任务执行一次,或者定期重复执行
方法摘要
void cancel()
终止此计时器,丢弃所有当前已安排的任务。
int purge()
从此计时器的任务队列中移除所有已取消的任务。
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)
安排指定的任务从指定的延迟后开始进行重复的固定延迟执行。
void scheduleAtFixedRate(TimerTask task, Date firstTime, long period)
安排指定的任务在指定的时间开始进行重复的固定速率执行。
void scheduleAtFixedRate(TimerTask task, long delay, long period)
安排指定的任务在指定的延迟后开始进行重复的固定速率执行。
2 TimerTask
java.lang.Object
|--- java.util.TimerTask
public abstract class TimerTaskextends Objectimplements Runnable
由 Timer 安排为一次执行或重复执行的任务
方法摘要
boolean cancel() 取消此计时器任务。
abstract void run() 此计时器任务要执行的操作。
long scheduledExecutionTime() 返回此任务最近实际 执行的已安排 执行时间。
3 案例
1 import java.util.TimerTask; 2 3 public class OneTask extends TimerTask{ 4 5 private int id; 6 public OneTask(int id){ 7 this.id = id; 8 } 9 10 @Override 11 public void run() { 12 System.out.println("线程"+ id +": 正在 执行。。"); 13 //System.gc(); 14 } 15 }
1 import java.util.Date; 2 import java.util.Timer; 3 4 public class Test1 { 5 6 public static void main(String[] args) { 7 Timer timer = new Timer(); 8 9 timer.schedule(new OneTask(1), 5000);// 5秒后启动任务 10 11 OneTask secondTask= new OneTask(2); 12 timer.schedule(secondTask, 1000, 3000);// 1秒后启动任务,以后每隔3秒执行一次线程 13 14 Date date = new Date(); 15 timer.schedule(new OneTask(3),new Date(date.getTime()+1000));//以date为参数,指定某个时间点执行线程 16 17 // timer.cancel(); 18 // secondTask.cancel(); 19 System.out.println("end in main thread..."); 20 } 21 }
Timer终止的问题:
默认情况下,只要一个程序的timer线程在运行,那么这个程序就会保持运行。可以通过以下3种方法终止一个timer线程:
(1)调用timer的cancle方法。你可以从程序的任何地方调用此方法,甚至在一个timer task的run方法里;
(2)让timer线程成为一个daemon线程(可以在创建timer时使用new Timer(true)达到这个目地),这样当程序只有daemon线程的时候,它就会自动终止运行;
(3)调用System.exit方法,使整个程序(所有线程)终止。
TimerTask也有cancel方法。
上面所说的“只要一个程序的timer线程在运行,那么这个程序就会保持运行”。
那么反过来,如果Timer里的所有TimerTask都执行完了,整个程序会退出吗,经测试答案是否定的,例如上面的测试代码,如果只加第一个TimerTask在Timer中执行:
timer.schedule(new OneTask(1), 5000);// 5秒后启动任务
那么5秒以后,其实整个程序还是没有退出,Timer会等待垃圾回收的时候被回收掉然后程序会得以退出,但是多长时间呢?
在TimerTask的run函数执行完以后加上System.gc();就可以了。
现在项目中用到需要定时去检查文件是否更新的功能。timer正好用于此处。
用法很简单,new一个timer,然后写一个timertask的子类即可。
代码如下:
1 package comz.autoupdatefile; 2 3 import java.util.Timer; 4 import java.util.TimerTask; 5 6 public class M { 7 public static void main(String[] args) { 8 // TODO todo.generated by zoer 9 Timer timer = new Timer(); 10 timer.schedule(new MyTask(), 1000, 2000); 11 } 12 } 13 14 class MyTask extends TimerTask { 15 16 @Override 17 public void run() { 18 System.out.println("dddd"); 19 20 } 21 22 }
这样,就可以在1秒钟之后开始执行mytask,每两秒钟执行一次。
当然,timer的功能也可以通过自己构造线程,然后在线程中用sleep来模拟停止一段时间,然后再执行某个动作。
其实,看一下timertask的源码就立即可以知道,timertask就是实现了runnable接口的。也就是说,通过timer来间隔一段时间执行一个操作,也是通过一个线程来做到的。
【这样就节省自己写线程的时间啦】