我正在wildfly 8.2上开发Java EE 7应用程序,并且需要运行定期后台任务。我注入执行人的服务和计划任务,这部分工作正常:避免在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的点,而该注入的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
}
所以基本的问题:我怎么能确保任务没有预定的两倍(甚至更多)?