ScheduledExecutorService
Для обеих ваших проблем, ScheduledExecutorService
является решением. Узнайте о Executors framework , встроенном в Java, чтобы сделать многопоточную работу намного проще и надежнее.
Запускать один раз в определенную дату / время
этот блок кода 15 ноября в 17.30
Служба исполнителя может запустить задачу после ожидания определенногоколичество времени.
Сначала определите момент для запуска.
ZoneId z = ZoneId.of( "America/Montreal" );
ZonedDateTime zdt = ZonedDateTime.of( 2020 , 11 , 15 , 17 , 30 , 0 , 0 , z );
Определите вашу задачу для запуска, затем.
Runnable runnable = new Runnable()
{
@Override
public void run ( )
{
System.out.println( "Runnable running. " + ZonedDateTime.now( z ) );
}
};
Получите службу исполнителя, поддержаннуюпул потоков.
ScheduledExecutorService scheduledExecutorService = Executors.newSingleThreadScheduledExecutor();
Вычислите, как ждать с этого момента до момента, когда задача должна быть запущена. Здесь мы используем класс Duration
для вычисления прошедшего времени. Мы передаем Instant
объекты, которые всегда находятся в UTC (смещение от UTC нуля часов, минут и секунд).
long delay = Duration.between( Instant.now() , zdt.toInstant() ).getSeconds(); // Calculate amount of time to wait until we run.
Скажите службе исполнителя выполнить задачу после ожидания этого периода времени. Убедитесь, что единица времени, используемая для вычисления длинного целого числа delay
, соответствует аргументу TimeUnit
.
scheduledExecutorService.schedule( runnable , delay , TimeUnit.SECONDS ); // ( Runnable , delay , TimeUnit of delay )
Если вы хотите отслеживать завершение этой задачи, захватите объект ScheduledFuture
, возвращаемый этим вызовом schedule
.
Выполнять повторно
запускать этот блок кода каждую среду в 15.30
Использовать код, аналогичный приведенному выше. В конце каждого запуска задачи рассчитайте время ожидания следующего запуска и снова вызовите scheduledExecutorService.schedule
. Таким образом, частью работы задачи является планирование следующего запуска.
Только что упомянутый подход должен соблюдаться, если вы хотите придерживаться строгого графика для времени суток и дня недели, как это видно в конкретном часовом поясе. Политики часто меняют смещение от UTC, используемое в их юрисдикциях, поэтому продолжительность дней варьируется. Поэтому мы не можем запланировать еженедельное задание на 7 дней * 24 часа * 60 минут * 60 секунд. Недели различаются по длине, поэтому мы должны каждый раз пересчитывать длину.
Если вы хотите запускать несколько раз с одинаковым промежутком времени, поэтому вам не нужны переменные часы населенного пункта, тогда используйте ScheduledExecutorService.scheduleAtFixedRate
или ScheduledExecutorService.scheduleWithFixedDelay
. Об этом уже много раз говорилось в Переполнении стека, поэтому ищите, чтобы узнать больше.