Я разрабатываю приложение Java EE 7 на wildfly 8.2 и вам нужно запустить периодическую фоновое задание. Я впрыснуть службу исполнителя и запланировать задачу, эта часть работает отлично:Избегайте дублирования задач в ManagedScheduledExecutorService
@Resource
private ManagedScheduledExecutorService executorService;
...
executorService.scheduleWithFixedDelay(() -> {
try {
// do some stuff
} catch (Throwable t) {
log.error("Error", t);
}
}, 0, 1, TimeUnit.MINUTES);
Сейчас (на самом деле хорошо) особенность в том, что после повторного развертывания запланированное задание сохраняется, и поэтому по-прежнему планируется в новом развертывании.
Но Как определить, запланировано ли задание, чтобы избежать его многократного планирования?
Я пытался использовать ScheduledFuture
и отменить задание на @PreDestroy
и @PrePassivate
reloadTreeFuture = executorService.scheduleWithFixedDelay(() -> {
...
@PreDestroy
@PrePassivate
protected void shutdown() {
reloadTreeFuture.cancel(true);
}
Это работает прекрасно, пока соответствующая задача не выполняется в тот самый момент отменить обжигают. Так как задача долгое время работает и работает часто, вероятность попадания ее в середине выполнения несколько высока.
Если отмена отменена, пока задача все еще выполняет отмену, похоже, ничего не делает. Он немедленно возвращается, и метод ScheduledFuture.isDone()
также возвращает true, но из журналов я вижу, что задача по-прежнему выполняется в фоновом режиме до тех пор, пока она не достигнет точки, где ему нужен инжектируемый компонент Bean, который недоступен из-за процесса развертывания. Затем процесс заканчивается org.jboss.msc.service.ServiceNotFoundException
- , но по-прежнему запланирован.
reloadTreeFuture.cancel(true);
while (!reloadTreeFuture.isDone()) {
Thread.sleep(200); // I know this is bad - it's just for testing
}
Так основной вопрос: как я могу убедиться, что задача не запланирована в два раза (или даже больше)?