Когда Java TimerTask запланирован в Timer, он уже "выполняется"? - PullRequest
11 голосов
/ 10 ноября 2011

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

timer.schedule(task, 60000);

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

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

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

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

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

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

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

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

Ответы [ 2 ]

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

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

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

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


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

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

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

Причины, почему ScheduledExecutorServiceэто предпочтительный способ, обозначенный здесь здесь :

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

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

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

4 голосов
/ 10 ноября 2011

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

...