Timer类帮助你建立在将来某个时候发生的任务,也包括重复的事件,每个Timer对象都包含一个与之相关联的线程,当它的TimerTask对象中的一个将要运行时,这个线程就被唤醒。
有三种任务调度方式:
- 一次性调度(once-only):任务只执行一次;
- 固定延时调度(fixed-delay):一次任务完成后再调度下一次的,时间延时是固定的
- 固定速率调度(fixed-rate):固定速率调度
一个TimerTask对象只能被一个Timer对象调度,而且被取消的Timer 不能再调度新的任务
例子:创建TimerTask类
- import java.util.Date;
- import java.util.TimerTask;
- /**
- * TimerTask类,将需要定时执行的任务写在run()方法中
- * */
- public class MemoryWatchTask extends TimerTask {
- @Override
- public void run() {
- Runtime run = Runtime.getRuntime();
- long free = run.freeMemory();
- long total = run.totalMemory();
- System.out.println(new Date()+"\t"+free+"\t"+total);
- }
- }
- import java.util.Date;
- import java.util.TimerTask;
- /**
- * TimerTask类,将需要定时执行的任务写在run()方法中
- * */
- public class MemoryWatchTask extends TimerTask {
- @Override
- public void run() {
- Runtime run = Runtime.getRuntime();
- long free = run.freeMemory();
- long total = run.totalMemory();
- System.out.println(new Date()+"\t"+free+"\t"+total);
- }
- }
import java.util.Date; import java.util.TimerTask; /** * TimerTask类,将需要定时执行的任务写在run()方法中 * */ public class MemoryWatchTask extends TimerTask { @Override public void run() { Runtime run = Runtime.getRuntime(); long free = run.freeMemory(); long total = run.totalMemory(); System.out.println(new Date()+"\t"+free+"\t"+total); } }
对任务类进行定时执行
- public static void main(String[] args) {
- //如果参数为true,则创建守护线程new Timer(true);
- Timer timer = new Timer();
- //延时0毫秒后启动,每隔1秒钟执行一次
- timer.scheduleAtFixedRate(new MemoryWatchTask(), 0, 1000);
- //在指定的时间开始执行第一次,每次间隔1秒钟
- //timer.scheduleAtFixedRate(new MemoryWatchTask(), new Date(), 1000);
- //在指定的时间进行一次性调度
- //timer.schedule(new MemoryWatchTask(), new Date());
- //在当前时间延时3秒钟进行一次性调度
- //timer.schedule(new MemoryWatchTask(), 3000);
- }
Timer与TimerTask是java中比较常用的类,可以定期重复执行某项任务。以前我还不知道这两个类是,一般用Thread来处理,虽然同样可以解决问题,但效率上可能就差了些。既然java内建了这两个类,那就必然有它们的好处了。
顾名思义,Timer应该是个计时器,而TimerTask是需要计时的任务。
下面通过一个小例子看看这两个类是如何让工作的:
- import java.util.Date;
- import java.util.Timer;
- import java.util.TimerTask;
- public class TimerTest extends TimerTask
- {
- private Timer timer;
- public static void main(String[] args)
- {
- TimerTest timerTest= new TimerTest();
- timerTest.timer = new Timer();
- //立刻开始执行timerTest任务,只执行一次
- timerTest.timer.schedule(timerTest,new Date());
- //立刻开始执行timerTest任务,执行完本次任务后,隔2秒再执行一次
- //timerTest.timer.schedule(timerTest,new Date(),2000);
- //一秒钟后开始执行timerTest任务,只执行一次
- //timerTest.timer.schedule(timerTest,1000);
- //一秒钟后开始执行timerTest任务,执行完本次任务后,隔2秒再执行一次
- //timerTest.timer.schedule(timerTest,1000,2000);
- //立刻开始执行timerTest任务,每隔2秒执行一次
- //timerTest.timer.scheduleAtFixedRate(timerTest,new Date(),2000);
- //一秒钟后开始执行timerTest任务,每隔2秒执行一次
- //timerTest.timer.scheduleAtFixedRate(timerTest,1000,2000);
- }
- @Override
- public void run()
- {
- System.out.println("Task is running!");
- }
- }
- import java.util.Date;
- import java.util.Timer;
- import java.util.TimerTask;
- public class TimerTest extends TimerTask
- {
- private Timer timer;
- public static void main(String[] args)
- {
- TimerTest timerTest= new TimerTest();
- timerTest.timer = new Timer();
- //立刻开始执行timerTest任务,只执行一次
- timerTest.timer.schedule(timerTest,new Date());
- //立刻开始执行timerTest任务,执行完本次任务后,隔2秒再执行一次
- //timerTest.timer.schedule(timerTest,new Date(),2000);
- //一秒钟后开始执行timerTest任务,只执行一次
- //timerTest.timer.schedule(timerTest,1000);
- //一秒钟后开始执行timerTest任务,执行完本次任务后,隔2秒再执行一次
- //timerTest.timer.schedule(timerTest,1000,2000);
- //立刻开始执行timerTest任务,每隔2秒执行一次
- //timerTest.timer.scheduleAtFixedRate(timerTest,new Date(),2000);
- //一秒钟后开始执行timerTest任务,每隔2秒执行一次
- //timerTest.timer.scheduleAtFixedRate(timerTest,1000,2000);
- }
- @Override
- public void run()
- {
- System.out.println("Task is running!");
- }
- }
import java.util.Date; import java.util.Timer; import java.util.TimerTask; public class TimerTest extends TimerTask { private Timer timer; public static void main(String[] args) { TimerTest timerTest= new TimerTest(); timerTest.timer = new Timer(); //立刻开始执行timerTest任务,只执行一次 timerTest.timer.schedule(timerTest,new Date()); //立刻开始执行timerTest任务,执行完本次任务后,隔2秒再执行一次 //timerTest.timer.schedule(timerTest,new Date(),2000); //一秒钟后开始执行timerTest任务,只执行一次 //timerTest.timer.schedule(timerTest,1000); //一秒钟后开始执行timerTest任务,执行完本次任务后,隔2秒再执行一次 //timerTest.timer.schedule(timerTest,1000,2000); //立刻开始执行timerTest任务,每隔2秒执行一次 //timerTest.timer.scheduleAtFixedRate(timerTest,new Date(),2000); //一秒钟后开始执行timerTest任务,每隔2秒执行一次 //timerTest.timer.scheduleAtFixedRate(timerTest,1000,2000); } @Override public void run() { System.out.println("Task is running!"); } }
需要注意的是scheduleAtFixedRate和schedule在参数完全相同的情况下,执行效果是不同的。上面例子中任务只是打印一个字符串,比较简单。但如果任务比较复杂,或者由于任何原因(如垃圾回收或其他后台活动)而延迟了某次执行,则scheduleAtFixedRate方法将快速连续地出现两次或更多的执行,从而使后续执行能够“追赶上来”;而schedule方法的后续执行也将被延迟。所以,在长期运行中,scheduleAtFixedRate执行的频率将正好是指定周期的倒数,schedule 执行的频率一般要稍慢于指定周期的倒数。
另外,TimerTask的构造函数是protected,所以无法再类中直接new一个TimerTask,而只能写一个类继承TimerTask。
知道了如何执行任务,那么如何终止任务呢?TimerTask与Timer都有cancel()方法。
- import java.util.Date;
- import java.util.Timer;
- import java.util.TimerTask;
- public class TimerTest extends TimerTask
- {
- private Timer timer;
- public static void main(String[] args)
- {
- TimerTest timerTest= new TimerTest();
- timerTest.timer = new Timer();
- //立刻开始执行timerTest任务,执行完本次任务后,隔2秒再执行一次
- timerTest.timer.schedule(timerTest,new Date(),2000);
- try
- {
- Thread.sleep(10000);
- } catch (InterruptedException e)
- {
- e.printStackTrace();
- }
- //结束任务执行,程序终止
- timerTest.timer.cancel();
- //结束任务执行,程序并不终止,为什么呢,还没想明白
- //timerTest.cancel();
- }
- @Override
- public void run()
- {
- System.out.println("Task is running!");
- }
- }