11

我想澄清一些关于 TimerTask 的事情。当您拥有以下代码时:

timer.schedule(task, 60000);

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

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

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

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

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

我相信我在 1 分钟延迟之前调用了 cancel()。但是怎么cancel返回false,

[task] 是否已经在执行?

希望你能给我线索/提示,甚至对此作出解释。谢谢!

4

2 回答 2

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

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

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

因此,如果您确定cancel在安排任务后 60 秒之前调用,您可能会调用它多次,并从后续的 中获得结果cancel,或者您正在对不同的任务调用取消。


一般来说,我会建议反对Timer支持ScheduledExecutorService

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

ScheduledExecutorService.schedule(callable, delay, timeunit)

此处概述了 ScheduledExecutorService 是首选方式的原因:

  • 定时器可以对系统时钟的变化敏感,ScheduledThreadPoolExecutor 不是

  • 定时器只有一个执行线程,所以长时间运行的任务会延迟其他任务。ScheduledThreadPoolExecutor 可以配置任意数量的线程。此外,如果需要,您可以完全控制创建的线程(通过提供 ThreadFactory)

  • TimerTask 中抛出的运行时异常杀死了那个线程,从而使 Timer 死了:-( ... 即计划任务将不再运行。ScheduledThreadExecutor 不仅捕获运行时异常,而且它允许您在需要时处理它们(通过覆盖 afterExecute 方法ThreadPoolExecutor). 抛出异常的任务将被取消,但其他任务将继续运行。

于 2011-11-10T03:47:50.723 回答
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.

于 2011-11-10T03:46:20.723 回答