Когда Java TimerTask запланирован в таймере, он уже "выполняет"?

Я хотел бы прояснить кое-что о TimerTask. Когда у вас есть код ниже:

timer.schedule(task, 60000);

где задача должна запускаться в течение следующих 1 минуты, уже выполняется объект задачи?

потому что где-то в моем коде я вызывал task.cancel(), но кажется, что вызов не предотвращает

выполняемая задача. Я даже зарегистрировал возвращаемое значение из вызова и возвращает false.

Я пришел к вопросу, когда прочитал документацию по методу отмены:

Отменяет TimerTask и удаляет его из очереди таймера. Как правило, он возвращает false, если вызов не помешал TimerTask от запуска хотя бы один раз. Последующие вызовы не влияют. Возвращает true, если вызов запретил выполнение запланированного выполнения, в противном случае - false.

Я считаю, что я вызвал cancel() до 1 минуты задержки. Но как получилось, отмена вернула false,

выполняется [задача] уже?

Надеюсь, вы можете дать мне подсказки/подсказки или даже объяснение этому. Спасибо, SO!

Ответ 1

  • где задача должна запускаться в течение следующих 1 минуты, уже выполняется объект задачи

Нет, он вызовет метод run этой задачи ровно через 60 секунд. Если task.cancel() возвращает false, это может означать 3 вещи:

  • задача была запланирована для однократного выполнения и уже выполнена OR
  • задача никогда не планировалась OR
  • задача была отменена OR

Следовательно, если вы уверены, что вы вызываете cancel до 60 секунд после планирования задачи, вы можете потенциально либо вызвать ее несколько раз, либо получить результат от последующего cancel, либо вы вызываете отмену на другая задача.


В общем, я бы рекомендовал против Timer в пользу ScheduledExecutorService

Вы можете добиться желаемой функциональности с помощью

ScheduledExecutorService.schedule(вызываемый, задержка, время)

Причины, по которым ScheduledExecutorService являются предпочтительным способом, обозначены здесь:

  • Таймер может быть чувствителен к изменениям в системных часах, ScheduledThreadPoolExecutor не

  • Таймер имеет только один поток выполнения, поэтому длительная задача может задержать другие задачи. ScheduledThreadPoolExecutor может быть настроен с любым количеством потоков. Кроме того, вы имеете полный контроль над созданными потоками, если хотите (предоставляя ThreadFactory)

  • Исключения, запущенные в TimerTask, убивают один поток, что делает Timer dead:-(... т.е. запланированные задачи больше не выполняются. ScheduledThreadExecutor не только улавливает исключения во время выполнения, но и позволяет обрабатывать их, если вы хотите (путем переопределения метода afterExecute из ThreadPoolExecutor). Задача, которая запустила исключение, будет отменена, но другие задачи будут продолжать выполняться.

Ответ 2

Я не знаю, почему ваш код возвращает 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.