定时器Timer的使用

概述

Timer类的主要作用是设置计划任务,但封装任务的类却是TimerTask类。执行计划任务的代码要放入TimerTask的子类中,因为TimerTask是一个抽象类。

方法schedule(task, delay)使用

schedule(task, delay)表示在将来的某个时间执行计划任务。

 1 /**
 2  * 任务类
 3  * @author ko
 4  *
 5  */
 6 public class MyTask extends TimerTask {
 7     @Override
 8     public void run() {
 9         System.out.println("get last info..."+new Date().toString());
10     }
11 }
 1 /**
 2  * 测试类
 3  * @author ko
 4  *
 5  */
 6 public class Test {
 7     public static void main(String[] args) {
 8         Timer timer = new Timer();
 9         Calendar calendar = Calendar.getInstance();
10         calendar.add(Calendar.SECOND, 3);
11         System.out.println("1 "+new Date().toString());
12         timer.schedule(new MyTask(), calendar.getTime());
13     }
14 }

在3s后执行计划任务,虽然结果打印正确,但是红色按钮却一直亮着,代表线程还在运行,那这是怎么回事?

那是因为new一个TimerTask就是开一个线程,这个线程不是守护线程,会一直运行,可以改成守护线程

Timer timer = new Timer(true);

程序立马执行,但是计划任务不执行了。

如果计划执行的时间在当前时间之前,那么任务会立即执行

如果有多个TimerTask在用一个Timer下要执行,那么TimerTask不一定会按计划的时间执行,因为前面的task耗时可能会超过下一个任务执行的时间

 1 /**
 2  * 测试类
 3  * @author ko
 4  *
 5  */
 6 public class Test {
 7     public static void main(String[] args) {
 8         Timer timer = new Timer(false);
 9         Calendar calendar = Calendar.getInstance();
10         calendar.add(Calendar.SECOND, 3);
11         System.out.println("1 "+new Date().toString());
12         timer.schedule(new MyTask(), calendar.getTime());
13         timer.schedule(new MyTask(), calendar.getTime());
14     }
15 }
测试类
 1 /**
 2  * 任务类
 3  * @author ko
 4  *
 5  */
 6 public class MyTask extends TimerTask {
 7     @Override
 8     public void run() {
 9         System.out.println("get last info..."+new Date().toString());
10         System.out.println("要耗时5s...");
11         try {
12             Thread.sleep(5000);
13         } catch (InterruptedException e) {
14             e.printStackTrace();
15         }
16     }
17 }
任务类

 schedule(new MyTask(), calendar.getTime(), 3000)

在某个时间点执行计划任务,并且之后每隔Xs再次执行。

 1 /**
 2  * 测试类
 3  * @author ko
 4  *
 5  */
 6 public class Test {
 7     public static void main(String[] args) {
 8         Timer timer = new Timer(false);
 9         Calendar calendar = Calendar.getInstance();
10         calendar.add(Calendar.SECOND, 3);
11         System.out.println("1 "+new Date().toString());
12         timer.schedule(new MyTask(), calendar.getTime(), 3000);
13     }
14 }
View Code
 1 /**
 2  * 任务类
 3  * @author ko
 4  *
 5  */
 6 public class MyTask extends TimerTask {
 7     @Override
 8     public void run() {
 9         System.out.println("get last info..."+new Date().toString());
10     }
11 }
View Code

TaskTimer的cancel()方法使用

该方法会将自身从任务队列中清楚,需要注意的是如果该方法执行的时候,任务正在执行的话,不会立即终止任务,而是会等本次任务执行完,不再启动下次任务。

 1 /**
 2  * 测试类
 3  * @author ko
 4  */
 5 public class Test {
 6     public static void main(String[] args) {
 7         Timer timer = new Timer(false);
 8         Calendar calendar = Calendar.getInstance();
 9         calendar.add(Calendar.SECOND, 3);
10         
11         MyTask t1 = new MyTask("t1");
12         timer.schedule(t1, calendar.getTime(),1000);
13         MyTask t2 = new MyTask("t2");
14         timer.schedule(t2, calendar.getTime(),1000);
15         
16         try {
17             Thread.sleep(5000);
18         } catch (InterruptedException e) {
19             e.printStackTrace();
20         }
21         t1.cancel();
22     }
23 }
View Code
 1 /**
 2  * 任务类
 3  * @author ko
 4  *
 5  */
 6 public class MyTask extends TimerTask {
 7     protected String tName;
 8     
 9     public MyTask(String tName) {
10         super();
11         this.tName = tName;
12     }
13 
14     @Override
15     public void run() {
16         System.out.println(tName + " get last info..."+new Date().toString());
17     }
18 }
View Code

可以看到执行t1任务被终止了。

Timer的cancel()方法使用

该方法会终止任务队列里的所有任务。

把上面代码的t1.cancel()换成timer.cancel()测试。

可以看到所有任务都被终止了。

scheduleAtFixedRate(task, delay, period)方法使用

scheduleAtFixedRate和schedule一样都会按顺序执行,所以不需要考虑非线程安全的情况。

scheduleAtFixedRate和schedule的区别只体现在不延时的情况下。

在不延时的情况下,schedule 下一次任务执行的时间参考的是上一次任务“开始”的时间。scheduleAtFixedRate下一次任务执行的时间参考的是上一次任务“结束”的时间。

在延迟的情况下,scheduleAtFixedRate和schedule都是参考的上一次任务“结束”的时间。

 

posted @ 2017-08-03 20:53  夏威夷8080  阅读(622)  评论(0编辑  收藏  举报