您的位置:首页 > 其它

Timer和TimerTask

2014-06-15 23:34 183 查看
 1. Timer和TimerTask

  Timer是jdk中提供的一个定时器工具,使用的时候会在主线程之外起一个单独的线程执行指定的计划任务,可以指定执行一次或者反复执行多次。

  TimerTask是一个实现了Runnable接口的抽象类,代表一个可以被Timer执行的任务。

  2. 一个Timer调度的例子

  复制代码

  1 import java.util.Timer;

  2 import java.util.TimerTask;

  3

  4 public class TestTimer {

  5

  6 public static void main(String args[]){

  7 System.out.println("About to schedule task.");

  8 new Reminder(3);

  9 System.out.println("Task scheduled.");

  10 }

  11

  12 public static class Reminder{

  13 Timer timer;

  14

  15 public Reminder(int sec){

  16 timer = new Timer();

  17 timer.schedule(new TimerTask(){

  18 public void run(){

  19 System.out.println("Time's up!");

  20 timer.cancel();

  21 }

  22 }, sec*1000);

  23 }

  24 }

  25 }

  复制代码

  运行之后,在console会首先看到:

  About to schedule task.

  Task scheduled.

  然后3秒钟后,看到

  Time's up!

  从这个例子可以看出一个典型的利用timer执行计划任务的过程如下:

  new一个TimerTask的子类,重写run方法来指定具体的任务,在这个例子里,我用匿名内部类的方式来实现了一个TimerTask的子类

  new一个Timer类,Timer的构造函数里会起一个单独的线程来执行计划任务。jdk的实现代码如下:

  复制代码

  1 public Timer() {

  2 this("Timer-" + serialNumber());

  3 }

  4

  5 public Timer(String name) {

  6 thread.setName(name);

  7 thread.start();

  8 }

  复制代码

  调用相关调度方法执行计划。这个例子调用的是schedule方法。

  任务完成,结束线程。这个例子是调用cancel方法结束线程。

  3. 如何终止Timer线程

  默认情况下,创建的timer线程会一直执行,主要有下面四种方式来终止timer线程:

  调用timer的cancle方法

  把timer线程设置成daemon线程,(new Timer(true)创建daemon线程),在jvm里,如果所有用户线程结束,那么守护线程也会被终止,不过这种方法一般不用。

  当所有任务执行结束后,删除对应timer对象的引用,线程也会被终止。

  调用System.exit方法终止程序

  4. 关于cancle方式终止线程

  这种方式终止timer线程,jdk的实现比较巧妙,稍微说一下。

  首先看cancle方法的源码:

  复制代码

  1 public void cancel() {

  2 synchronized(queue) {

  3 thread.newTasksMayBeScheduled = false;

  4 queue.clear();

  5 queue.notify(); // In case queue was already empty.

  6 }

  7 }

  复制代码

  没有显式的线程stop方法,而是调用了queue的clear方法和queue的notify方法,clear是个自定义方法,notify是Objec自带的方法,很明显是去唤醒wait方法的。

  再看clear方法:

  复制代码

  1 void clear() {

  2 // Null out task references to prevent memory leak

  3 for (int i=1; i<=size; i++)

  4 queue[i] = null;

  5

  6 size = 0;

  7 }

  复制代码

  clear方法很简单,就是去清空queue,queue是一个TimerTask的数组,然后把queue的size重置成0,变成empty.还是没有看到显式的停止线程方法,回到最开始new Timer的时候,看看new Timer代码:

  复制代码

  1 public Timer() {

  2 this("Timer-" + serialNumber());

  3 }

  4

  5 public Timer(String name) {

  6 thread.setName(name);

  7 thread.start();

  8 }
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: