【问题标题】:Avoid duplicate tasks in ManagedScheduledExecutorService避免 ManagedScheduledExecutorService 中的重复任务
【发布时间】:2016-01-20 02:52:24
【问题描述】:

我正在 Wildfly 8.2 上开发 Java EE 7 应用程序,并且需要运行定期后台任务。我注入了一个执行器服务并安排了一个任务,这部分工作正常:

@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
  }

这么基本的问题:我怎样才能确保任务不会被安排两次(甚至更多)?

【问题讨论】:

    标签: wildfly-8 java-ee-7


    【解决方案1】:

    您可以记下每个任务的 id 并在执行前检查它们。当然,这可能不是最佳解决方案,但它确实有效。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-06-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-12-04
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多