TimerTask继续运行

时间:2010-08-17 03:04:01

标签: java multithreading task schedule

我对Java中Timer类的行为有疑问。 这是代码:http://pastebin.com/mqcL9b1n

public class Main {

    public static void main(String[] args) {
        Main m = new Main();
        m.foo();
        m = null;
    }

    public void foo()
    {
        Timer t = new Timer();
        t.schedule(new SysPrint(), 200);
    }

}

class SysPrint extends TimerTask
{
    public void run()
    {
        System.out.println("Yes!");
    }
}

如果您运行该程序,它会打印出“是的!”并且它不会做任何其他事情(程序没有结束)。

Java文档说: 在对Timer对象的最后一次实时引用消失并且所有未完成的任务都已完成执行之后,计时器的任务执行线程正常终止(并且变为垃圾回收)。

正如我看到的那样,在'foo()'函数结束后,Timer对象的“最后一次实时引用”消失了。计划的唯一任务就是“是的!”已执行的任务,所以我想在打印出“是!”的过程之后,Timer对象应该结束并且进程应该终止。

这里发生了什么?

3 个答案:

答案 0 :(得分:2)

Java没有退出,因为运行Timer的线程仍在继续。在Java退出之前,您必须将该线程标记为守护程序线程。您可能无法访问该线程本身,因此除非Timer有一个方法来标记它,所以您将很难做到这一点。您需要在finally子句中手动停止它。

try {
   timer = new Timer();
   timer.schedule( new SysPrint(), 200 );
} finally {
   timer.cancel();
}

答案 1 :(得分:0)

我相信下面的代码可以解决问题。

public class Main {
  public static void main(String[] args) {
    Main m = new Main();
    m.foo();
    m = null;
  }

  public void foo() {
    Timer t = new Timer();
    t.schedule(new SysPrint(), 200);
  }
}

class SysPrint extends TimerTask {
  SysPrint(Timer timer) {
    this.timer = timer;
  }

  public void run() {
    System.out.println("Yes!");
    timer.cancel();
  }

  private Timer timer;
}

答案 2 :(得分:0)

创建Timer对象时。创建一个TimerThread。并且它是运行任务的内部线程。您可以查看TimerThread的方法run()。您可以看到它有一个while循环。

 private void mainLoop() {
    while (true) {....

TimerThread未设置为守护程序,因此main方法完全执行,JVM不存在。

这就是为什么您的程序始终运行而不停止的原因。