简体   繁体   English

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

[英]When a Java TimerTask is scheduled in a Timer, is it already “executing”?

I would like to clarify something about TimerTask. 我想澄清一下有关TimerTask的内容。 When you have the code below: 如果您有以下代码:

timer.schedule(task, 60000);

where the task is scheduled to run in the next 1 minute, is the task object already executing? 如果任务计划在接下来的1分钟内运行,那么任务对象是否已在执行?

because somewhere in my code I called task.cancel() but it seems that the call doesn't prevent 因为在我的代码中某处我调用了task.cancel()但似乎调用并没有阻止

task to be executed. 要执行的任务。 I even logged the return value from the call and it returns false. 我甚至记录了来自调用的返回值,它返回false。

I came about my question when I read the documentation for the cancel method: 当我阅读取消方法的文档时,我想到了我的问题:

Cancels the TimerTask and removes it from the Timer's queue. 取消TimerTask并将其从Timer的队列中删除。 Generally, it returns false if the call did not prevent a TimerTask from running at least once. 通常,如果调用没有阻止TimerTask至少运行一次,则返回false。 Subsequent calls have no effect. 后续调用无效。 Returns true if the call prevented a scheduled execution from taking place, false otherwise. 如果调用阻止了计划执行,则返回true,否则返回false。

I believe I called cancel() before the 1 minute delay. 我相信我在1分钟的延迟之前打电话给cancel()。 But how come cancel returned false, 但是如何取消返回false,

is it [task] already executing? 是[任务]已经执行了吗?

Hope you can give me clues/hints or even an explanation to this. 希望你能给我提供线索/提示甚至解释。 Thanks SO! 谢谢!

  • where the task is scheduled to run in the next 1 minute, is the task object already executing 如果任务计划在接下来的1分钟内运行,则任务对象已在执行

No, it is going to invoke the run method of this task in exactly 60 seconds. 不,它将在60秒内调用此任务的run方法。 If task.cancel() returns false , that could mean 3 things: 如果task.cancel()返回false ,那可能意味着三件事:

  • the task was scheduled for one-time execution and has already run OR 任务被安排一次性执行,并且已经运行了OR
  • the task was never scheduled OR 任务从未安排过
  • the task was already cancelled OR 任务已被取消或

Hence, if you are certain that you call cancel before 60 seconds after scheduling the task, you could potentially either call it several times, and get a result from a subsequent cancel , OR you are calling cancel on a different task. 因此,如果您确定在安排任务后60秒内调用cancel ,则可能会多次调用它,并从后续cancel获取结果,或者您在其他任务上调用取消。


In general, I would recommend against Timer in favor of a ScheduledExecutorService 一般来说,我建议使用Timer来支持ScheduledExecutorService

You can achieve a desired functionality with: 您可以通过以下方式实现所需的功能

ScheduledExecutorService.schedule( callable, delay, timeunit ) ScheduledExecutorService.schedule(可调用,延迟,timeunit)

Reasons why ScheduledExecutorService are is a preferred way are outlined here : 这里概述 ScheduledExecutorService是首选方式的原因:

  • Timer can be sensitive to changes in the system clock, ScheduledThreadPoolExecutor isn't 定时器可以对系统时钟的变化敏感,而ScheduledThreadPoolExecutor则不然

  • Timer has only one execution thread, so long-running task can delay other tasks. Timer只有一个执行线程,因此长时间运行的任务可以延迟其他任务。 ScheduledThreadPoolExecutor can be configured with any number of threads. ScheduledThreadPoolExecutor可以配置任意数量的线程。 Furthermore, you have full control over created threads, if you want (by providing ThreadFactory) 此外,如果需要,您可以完全控制创建的线程(通过提供ThreadFactory)

  • runtime exceptions thrown in TimerTask kill that one thread, thus making Timer dead :-( ... ie scheduled tasks will not run anymore. ScheduledThreadExecutor not only catches runtime exceptions, but it lets you handle them if you want (by overriding afterExecute method from ThreadPoolExecutor). Task which threw exception will be canceled, but other tasks will continue to run. 在TimerTask中抛出的运行时异常会杀死一个线程,从而使得计时器死机:-(...即计划任务将不再运行.ScheduledThreadExecutor不仅捕获运行时异常,而且它允许您根据需要处理它们(通过覆盖afterExecute方法) ThreadPoolExecutor)。抛出异常的任务将被取消,但其他任务将继续运行。

I don't know why your code returns false . 我不知道为什么你的代码返回false

The following code prints true . 以下代码打印为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());
    }
}

If the last println is commented, the program prints hi . 如果对最后一个println进行了注释,则程序打印为hi

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM