2015-10-21 32 views
1

我正在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 
    } 

所以基本的问题:我怎么能确保任务没有预定的两倍(甚至更多)?

回答

0

您可以记下每个任务的ID并在执行前检查它们。当然,这可能不是最好的解决方案,但它的工作原理。