在Timer中调度Java TimerTask时,它是否已经“正在执行”?

时间:2011-11-10 03:27:59

标签: java timer timertask

我想澄清一下有关TimerTask的内容。如果您有以下代码:

timer.schedule(task, 60000);

任务计划在接下来的1分钟内运行,任务对象是否已经执行?

因为在我的代码中某处我调用了task.cancel()但似乎调用没有阻止

要执行的任务。我甚至记录了调用的返回值,它返回false。

当我阅读取消方法的文档时,我想到了我的问题:

  

取消TimerTask并将其从Timer的队列中删除。   通常,如果调用没有阻止TimerTask,则返回false   从至少运行一次。后续调用无效。如果调用阻止了计划执行,则返回true,否则返回false。

我相信在延迟1分钟之前我打电话给cancel()。但是如何取消返回false,

是[任务]已经执行了吗?

希望你能给我提供线索/提示甚至解释。谢谢!

2 个答案:

答案 0 :(得分:18)

  • 任务计划在接下来的1分钟内运行,任务对象已在执行

不,它将在60秒内调用此任务的run方法。如果task.cancel()返回false,则可能意味着3件事:

  • 任务已安排一次性执行且已经运行OR
  • 任务从未安排或
  • 任务已被取消或

因此,如果您确定在安排任务后60秒之前调用cancel,您可能会多次调用它,并从后续cancel获得结果,或者您是在另一个任务上调用取消。


一般情况下,我建议反对Timer支持ScheduledExecutorService

您可以通过以下方式实现所需的功能:

ScheduledExecutorService.schedule( callable, delay, timeunit )

优先考虑ScheduledExecutorService的原因here

  • 计时器可能对系统时钟的变化很敏感,ScheduledThreadPoolExecutor不是

  • Timer只有一个执行线程,因此长时间运行的任务可以延迟其他任务。 ScheduledThreadPoolExecutor可以配置任意数量的线程。此外,如果需要(通过提供ThreadFactory)

  • ,您可以完全控制已创建的线程
  • 在TimerTask中抛出的运行时异常会杀掉一个线程,从而使得计时器死机:-(...即计划任务将不再运行.ScheduledThreadExecutor不仅捕获运行时异常,而且如果你想要它可以让你处理它们(通过从ThreadPoolExecutor覆盖afterExecute方法)。抛出异常的任务将被取消,但其他任务将继续运行。

答案 1 :(得分:4)

我不知道您的代码返回false的原因。

以下代码打印true

import java.util.Timer;
import java.util.TimerTask;


public class Test {
    public static void main(String[] args) {
        Timer timer = new Timer();
        TimerTask task = new TimerTask() {

            @Override
            public void run() {
                System.out.println("hi");
            }

        };
        timer.schedule(task, 60000);
        System.out.println(task.cancel());
    }
}

如果评论了最后一个println,程序将打印hi