Java: Как запустить этот код только один раз в указанное время? - PullRequest
0 голосов
/ 23 января 2020

Я пытаюсь запустить метод один раз в неделю. Например, каждый понедельник 8 вечера. Я использую этот код:

    Timer timer = new Timer();

    Calendar calendar = Calendar.getInstance();
    calendar.set(Calendar.DAY_OF_WEEK, Calendar.MONDAY);
    calendar.set(Calendar.HOUR_OF_DAY, 20);
    calendar.set(Calendar.MINUTE, 00);
    calendar.set(Calendar.SECOND, 00);
    Date time = calendar.getTime();

    timer.schedule(new PrintTask(),
            time);

    // other code where variable gets increased



public class PrintTask extends TimerTask {
    public void run() {

          variable = 0;
    }
}

Однако, если я прав, код dosomething выполняется непрерывно - пока календарное время уже прошло. Например, сейчас уже понедельник, поэтому код dosomething выполняется постоянно. Variabele увеличивается, но он должен быть сброшен до 0 в понедельник. Переменная теперь постоянно равна 0, потому что она сбрасывается снова и снова. Если я использую calendar.set(Calendar.DAY_OF_WEEK, Calendar.SUNDAY);, переменная не сбрасывается, потому что это еще не было воскресенье. Но как только наступит воскресенье в 8 вечера, он, вероятно, продолжит сбрасывать остаток этого дня.

Я хочу, чтобы код dosomething выполнялся только один раз в указанное время. Может кто-нибудь сказать мне, как настроить код для достижения этой цели?

Извините за мой Engli sh

Ответы [ 2 ]

0 голосов
/ 23 января 2020

Класс Timer можно использовать для планирования запуска вещей один или несколько раз. То, как вы планируете это в данный момент, будет выполнено только один раз в указанное время.

https://docs.oracle.com/javase/7/docs/api/java/util/Timer.html#schedule (java .util.TimerTask,% 20 java .util.Date)

Существуют лучшие варианты, если вы хотите запланировать задачи, например, ScheduledExecutorService:

https://docs.oracle.com/javase/7/docs/api/java/util/concurrent/ScheduledExecutorService.html

Согласно Java Практический параллелизм:

  1. Таймер может быть чувствителен к изменениям системных часов, ScheduledThreadPoolExecutor - нет.
  2. Таймер имеет только один поток выполнения, поэтому он работает долго задача может задержать другие задачи. ScheduledThreadPoolExecutor может быть настроен с любым количеством потоков. Кроме того, вы имеете полный контроль над созданными потоками, если хотите (предоставляя ThreadFactory).
  3. Исключения времени выполнения, выброшенные в TimerTask, убивают этот поток, что делает Timer мертвым :-( ... т.е. запланированные задачи не будут больше не запускается. ScheduledThreadExecutor не только перехватывает исключения во время выполнения, но и позволяет вам обрабатывать их, если хотите (путем переопределения метода afterExecute из ThreadPoolExecutor). Задача, вызвавшая исключение, будет отменена, но другие задачи продолжат выполняться.

http://jcip.net/

0 голосов
/ 23 января 2020

Пожалуйста, посмотрите на этот вопрос здесь ( Как я могу запускать свою TimerTask каждый день в 2 часа дня ). Это почти решает проблему такого же типа.

Отмените таймер с помощью cancel api Timer и перепланируйте таймер внутри run () метод; это должно препятствовать обновлению переменной каждый раз.

...