Служба исполнителя
Определить Runnable
(или Callable
). Это означает просто наличие run
метода для соответствия контракту интерфейса.
В лямбда-синтаксисе:
Runnable runnable =
() -> {
System.out.println( "Looking up fresh stock prices at " + Instant.now().toString() ) ;
}
;
Далее, изучите структуру Executors, встроенную в современный Java. См. Oracle Учебное пособие . Эта структура значительно упрощает сложную работу по планированию потоков.
В частности, вы хотите использовать ScheduledExecutorService
. Этот интерфейс предназначен для планирования запуска задачи один раз в определенное время c (фактически, запуск один раз после истечения указанной задержки c), или повторного запуска задачи. Вы, конечно, хотите первое.
Получить реализацию из класса Executors
. Для ваших нужд нам нужен только один поток. В других случаях вы можете захотеть использовать пул потоков.
ScheduledExecutorService ses = Executors.newSingleThreadScheduledExecutor() ;
Укажите, как долго ждать, задержку, пока задача не будет выполнена. Вычислите время, необходимое для ожидания.
Укажите целевую дату. В реальной работе я бы убедился, что дата действительно в будущем.
LocalDate localDate = LocalDate.of( 2020 , Month.FEBRUARY , 23 ) ;
Нам нужен определенный c момент, а не просто дата. Я полагаю, вы хотели бы первый момент этого дня. Не думайте, что это 00:00. Некоторые дни в некоторых зонах в некоторые даты могут начинаться в другое время, например 01:00. Всегда позволяйте java .time определять первый момент.
ZoneId z = ZoneId.of( "Africa/Tunis" ) ;
ZonedDateTime zdt = localDate.atStartOfDay( z ) ;
Преобразовать из этого часового пояса в UT C.
Instant then = zdt.toInstant() ;
Захватить текущий момент, как показано в UT C.
Instant now = Instant.now() ;
Рассчитайте прошедшее время как Duration
.
Duration d = Duration.between( now , then ) ;
Теперь запланируйте выполнение нашей задачи после истечения задержки. Я предлагаю добавить немного времени, чтобы убедиться, что все часы всех связанных систем вписываются в новый день. Плюс полночь, как правило, Час ведьм для вычислений, с большим количеством заданий cron, прокруткой журналов, утилитами и отчетами. Может быть, добавить несколько минут или больше.
ses.scheduleWithFixedDelay( runnable , d.plusMinutes( 7 ).toMinutes() , TimeUnit.MINUTES);
Вы можете захватить возвращенные значения ScheduledFuture
для мониторинга вашей задачи.
ВАЖНО Обязательно корректно завершите работу службы исполнителя, если она больше не нужна или когда приложение закрывается. В противном случае ваши потоки могут продолжать работать в фоновом режиме, пережив выход из вашего приложения.
ses.shutdown() ;