[英]Java Timer Thread Operation
我正在使用 Timer Thread 运行简单的打印 function。 问题是,如果我将延迟时间设置为 1000 毫秒,程序将直接退出而没有任何 output。
但如果我切换到 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");
}
}
我想也许主线程运行得太快了。 但是有没有人可以告诉我,如果我是对的还是不对...
实际上,您的应用程序可能仍在运行(或应该运行),无论计划的超时如何。 根据JavaDocs ,使用默认构造函数创建Timer
将创建一个用户线程,因此它“能够防止应用程序终止”。
如果您使用调试器运行应用程序,您应该会看到计时器线程在后台保持活动状态,如下所示
Thread[Timer-0](Running)
更改Timer
以使用守护线程代替
Timer timer = new Timer(true);
将显示线程实际上在main()
完成时立即终止,并以程序的 rest 结束:
terminated, exit value 0
使用ideone尝试您的代码还可以验证程序在main()
之后不会终止,而是继续执行直到 JVM 终止(有一个内置的 5 秒超时),然后打印预期的 output。
output 是否在预定时间或应用程序退出时打印,可能取决于底层操作系统和 JVM。
请参阅Java 中的等待计时器完成。 本质上,您的主线程在 Timer 计划发生之前完成。
schedule 方法将以指定的延迟调用您的任务。 您的情况为 1000 毫秒或 100 毫秒。
从您的代码中,主线程将运行该调度程序,然后退出。 您认为 100 毫秒延迟会很好的假设并不总是正确的。 您的系统可能会以超过 100 毫秒的速度运行主线程并且没有时间运行您的任务。 这就是大家所说的“种族条件”。
你开始你的任务,然后你的程序结束。 在退出程序之前,您需要等待计时器/任务完成:
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<int>
之类的外部跟踪任务开始和停止。 这可能容易出错并导致程序提前退出或永远休眠。
我会用调度程序 go 。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.