Java定时器线程操作



我正在使用Timer Thread运行一个简单的打印函数。问题是,如果我将延迟时间设置为1000ms,程序将在没有任何输出的情况下退出。

但如果我切换到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](正在运行(

Timer更改为使用后台进程线程,而不是使用

Timer timer = new Timer(true);

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

terminated,exit value 0

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

输出是否在计划时间或应用程序退出时打印,可能取决于底层操作系统和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
}

上述解决方案有点糟糕。一个更好的方法是给你一些调度器,让你等到它的所有任务都完成了@联邦调查局的链接表明ScheduledExecutorService

另一个替代方案是从外部跟踪任务开始&以类似Atomic<int>的内容停止。这可能容易出错,并导致程序提前退出,或者永远休眠。

我会按照时间表去。

最新更新