【问题标题】:Java Timer Thread OperationJava 定时器线程操作
【发布时间】:2020-02-25 02:18:13
【问题描述】:

我正在使用 Timer Thread 来运行一个简单的打印功能。问题是,如果我将延迟时间设置为 1000 毫秒,程序将直接退出而没有任何输出。

但如果我切换到 100 毫秒,程序就可以了。

public class TimerTaskTest01 {
    public static void main(String[] args) {
        Timer timer = new Timer();
        timer.schedule(new MyTask(), 1000);
    }
}
class MyTask extends TimerTask {
    @Override
    public void run() {
        for (int i = 0; i < 10; i++) {
            System.out.println("Hello World... ");
        }
        System.out.println("END");
    }
}

我想也许主线程运行得太快了。但是有没有人可以告诉我我是对还是错...

【问题讨论】:

  • 您是如何执行程序的,您使用的是哪个 JDK?即使从 Eclipse IDE 和 JDK 8 运行延迟 10 秒,我也无法重现该问题。

标签: java


【解决方案1】:

实际上,您的应用程序可能仍在运行(或应该运行),而不管计划的超时时间如何。根据JavaDocs,使用默认构造函数创建Timer 将创建一个用户线程,因此它“能够防止应用程序终止”。

如果您使用调试器运行应用程序,您应该会看到计时器线程在后台保持活动状态,类似于

线程[Timer-0](运行中)

Timer 更改为使用守护线程 代替

Timer timer = new Timer(true);

main() 完成时,将显示线程实际上与程序的其余部分一起立即终止:

终止,退出值 0

使用ideone 尝试您的代码还可以验证程序在main() 之后不会终止,而是继续执行直到 JVM 终止(有一个内置的 5 秒超时),之后预期的输出被打印出来了。

输出是否在预定时间或应用程序退出时打印,可能取决于底层操作系统和JVM。

【讨论】:

  • 我同意这一点。在普通应用程序中使用时 (main(...))。然而,当在一个简单的 jUnit 测试用例中使用时,结果是不同的,它实际上退出并表现得像一个守护进程,而不管选项如何。不过,这似乎是一个 jUnit 问题。
【解决方案2】:

看到这个Waiting for a Timer to finish in Java。本质上,您的主线程在 Timer 计划发生之前就完成了。

【讨论】:

  • Timer 的默认构造函数启动一个用户线程(不是守护进程),根据@987654322,它应该“能够防止应用程序终止” @.
【解决方案3】:

schedule 方法将以指定的延迟调用您的任务。 1000 毫秒或 100 毫秒,适合您的情况。

从您的代码中,主线程将运行该调度程序,然后退出。您认为 100 毫秒延迟会很好的假设并不总是正确的。您的系统可能会以超过 100 毫秒的速度运行主线程并且没有时间运行您的任务。 这就是大家所说的“种族条件”。

【讨论】:

    【解决方案4】:

    您开始您的任务,然后您的程序结束。在退出程序之前,您需要等待计时器/任务完成:

    public static void main(String[] args) {
        Timer timer = new Timer();
        int sleepTimeMS = 1000;
        timer.schedule(new MyTask(), sleepTimeMS);
        Thread.sleep(sleepTimeMS + 50); // just in case, an extra 50ms
    }
    

    上面的解决方案有点糟糕。一个更好的方法是给你一些调度程序,让你等到它的所有任务都完成。 @fedup 的链接建议ScheduledExecutorService

    另一种选择是使用Atomic&lt;int&gt; 之类的外部跟踪任务开始和停止。这可能容易出错并导致程序提前退出或永远休眠。

    我会选择调度程序。

    【讨论】:

      猜你喜欢
      • 2011-05-24
      • 2020-02-20
      • 1970-01-01
      • 2021-12-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-28
      相关资源
      最近更新 更多