ПланируютЭксексуалСерВервис. ScheduleAtfixedrate и установка инициации на сегодняшний день в прошлом
-
02-10-2019 - |
Вопрос
Я работаю над системой планирования в Java, которая отправляет напоминания на основе Дата начала, Дата окончания и вхождение (почасовой, ежедневно, еженедельный, ежемесячный, понедельник и т. Д.). Первоначально я использовал Таймер и TimetArk. Классы для планирования напоминаний:
Timer timer = new Timer();
timer.scheduleAtFixedRate(reminder, firstDate, period);
Я недавно перешел на Планируемоеexecutorservice Таким образом, у меня может быть больше контроля на отмене событий. То Планируемоеexecutorservice работает хорошо для повторяющихся напоминаний, за исключением одного случая перенесения напоминания с Дата начала в прошлом. То ШНУКСФИКСЕДЕНИЕ Функция позволяет только указывать длинный ценность для initialdelay., а не фактический Дата объект:
ScheduledExecutorService scheduler = Executors.newSingleThreadScheduledExecutor();
scheduler.scheduleAtFixedRate(reminder, initialDelay, period, unit);
Это представляет проблему, поскольку передача в отрицательном initialdelay. все еще приводит к тому, что мероприятие будет сразу же, что вызывает его повторять в Теперь + период, скорее, чем Дата начала + период.
Любые идеи, как я могу (Re) запланировать напоминание с Дата начала в прошлом?
Решение
Просто сделайте быструю проверку, чтобы увидеть, в прошлом дата, создайте новое время временного начала DateTime, которое сейчас приращение начала прошлого.
Другие советы
Я решил его, запустив его один раз на запуск, а затем в то время, когда я хотел каждый день:
// check once initial on startup
doSomething();
// and then once every day at midnight utc
ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1);
LocalDateTime firstRun = LocalDate.now(ZoneOffset.UTC).atStartOfDay().plusDays(1);
Duration durationUntilStart = Duration.between(LocalDateTime.now(ZoneOffset.UTC), firstRun);
scheduler.scheduleAtFixedRate(
() -> doSomething(),
durationUntilStart.getSeconds() + 1,
Duration.ofDays(1).getSeconds(),
TimeUnit.SECONDS
);