使java.util.Timer成为守护进程的正确方法

时间:2011-02-14 17:53:36

标签: java

我有以下java.util.Timer但它似乎没有执行,我不知道为什么。

public static void main(String[] args)
{
  Timer to = new Timer(true);

  System.out.println("Now=" + System.currentTimeMillis());
  to.schedule(new TimeOutTask("Short#1 - 250"), 250);
  to.schedule(new TimeOutTask("Long - 10050"), 10050);
  to.schedule(new TimeOutTask("Short#2 - 250"), 250);
  to.schedule(new TimeOutTask("Medium - 5050"), 5050);
  to.schedule(new TimeOutTask("Short#3 - 250"), 250);
}

所有TimeOutTask都会打印传递的字符串和当前时间。当守护程序标志为false时,应用程序不会终止,我看到了:

Now=1297705592543
Short#1 - 250:1297705592793
Short#3 - 250:1297705592793
Short#2 - 250:1297705592793
Medium - 5050:1297705597605
Long - 10050:1297705602605

如果为true,则应用程序终止,我看到了:

Now=1297705249422

我只是想找到一种方法来监控多个任务以达到超时目的;我不希望监视超时的线程阻止应用程序终止。所以我想要守护进程但是当我把它作为守护进程时,我的任务似乎都没有执行?!?!

编辑:

有趣的是,我认为我的问题源于我孤立地尝试新想法的方式。如果我有一个真正的应用程序运行它将保持守护程序线程活着,因为这些线程只代表超时我不关心它们是否完成主应用程序完成。

我将此代码添加到我的main方法的末尾以弹出框架并通过在不同时间关闭它进行测试。如果我等待的时间足够长,我的所有线程都会执行,如果不这样做,那么即使某些任务没有执行,应用程序也会正常终止。

JFrame f = new JFrame("Test Frame");
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

f.setVisible(true);

感谢您的帮助。

3 个答案:

答案 0 :(得分:5)

当你将它作为一个守护程序线程时,你的主线程在安排定时器后立即完成,并且没有什么能阻止应用程序退出。你需要下定决心:要么你想让计时器线程保持应用程序活着,要么你不想。你不可能两种方式:)

如果您希望将其保持活动足够长的时间以完成所有计划任务,则添加额外的计划任务以停止计时器,并在最新任务之后安排计时。

答案 1 :(得分:4)

正如其他答案所描述的那样,您的JVM终止于main()的末尾。您需要保持应用程序退出,直到完成最终任务。这是一个(不可否认的黑客攻击)示例,它弹出一个窗口,其中有一个按钮以退出应用程序:

import java.util.*;
import java.awt.*;
import java.awt.event.*;

public class TimerTest extends Frame implements ActionListener {
    Timer to;

    TimerTest() {
    to = new Timer(true);

        System.out.println("Now=" + System.currentTimeMillis());
        to.schedule(new TimeOutTask("Short#1 - 250"), 250);
        to.schedule(new TimeOutTask("Long - 10050"), 10050);
        to.schedule(new TimeOutTask("Short#2 - 250"), 250);
        to.schedule(new TimeOutTask("Medium - 5050"), 5050);
        to.schedule(new TimeOutTask("Short#3 - 250"), 250);

        Button b = new Button("Click to exit");
        b.addActionListener(this);
        this.add(b);
        this.pack();
        this.setVisible(true);
    }

    public static void main(String[] args) {
        TimerTest t = new TimerTest();
    }

    public void actionPerformed(ActionEvent a) {
        this.dispose();
    }
}

class TimeOutTask extends TimerTask {
    String s;

        TimeOutTask(String s) {
        this.s = s;
    }

    public void run() {
        System.out.println(s);
    }
}

定时任务将出现在命令行中,就像您在示例中尝试的那样,但是会弹出一个框架。无论任务是否完成,“单击退出”按钮都将关闭应用程序。我希望这个例子可以帮助你。

答案 2 :(得分:0)

daemon Thread的Javas定义是它们不会阻止您的应用程序终止。一旦只有守护程序线程仍然存在,jvm实例就会终止,从而终止所有剩余的守护程序线程。

它们并不意味着在后台运行您的应用程序,如果您想这样做,您必须将其作为后台任务启动或以平台相关的方式生成新的jvm。