调度并运行TimerTask后,Java程序永远不会退出

时间:2013-05-23 20:51:01

标签: java scheduling deadlock

我有这个简单的Java代码,应安排在1毫秒内运行然后退出。

import java.util.*;

class A {
    public static void main(String[] args) {
        new Timer().schedule(new TimerTask() {
            public void run() {
                System.out.println("hello");
            }
        }, 1);
        System.out.println("hi");
    }
}

它永不退出。为什么呢?

$ javac A.java && java A
hi
hello

如果我删除设置时间表的代码,它就可以了。为什么呢?

1 个答案:

答案 0 :(得分:2)

documentation of java.util.Timer说:

  

如果调用者想要快速终止定时器的任务执行线程,调用者应该调用定时器的cancel方法。

那是你应该做的 。罗伯特·哈维(Robert Harvey)与某些内容相关联,这些内容会在你的问题下向你展示如何作为评论。

使用您的代码,这会打印与您的代码相同的内容,但随后退出:

public static void main(String[] args) {
    final Timer timer = new Timer();
    timer.schedule(new TimerTask() {
        public void run() {
            System.out.println("hello");
            timer.cancel();
        }
    }, 1);
    System.out.println("hi");        
}

或者,您可以通过如下方式创建计时器来使计时器成为守护程序:

public static void main(String[] args) {
    final Timer timer = new Timer(true);
    timer.schedule(new TimerTask() {
        public void run() {
            System.out.println("hello");
        }
    }, 1);
    System.out.println("hi");
}

问题是这可以在任务运行之前退出并提供如下输出:

hi
<exit>

public Timer(boolean isDaemon)的{​​{3}}解释了原因:

  

创建一个新的计时器,可以指定其关联的线程作为守护程序运行。如果定时器将用于安排重复的“维护活动”,则调用守护程序线程,只要应用程序正在运行,该活动必须执行,但不应延长应用程序的生命周期。