如何确定@scheduled 任务终止?

How to be sure that a @scheduled task terminates?

在 Spring 网络应用程序中,我有一个每五分钟调用一次的计划任务。

 @Scheduled(fixedDelay = 300000)
     public void importDataTask()
{
    importData(); //db calls, file manipulations, etc..
}

通常任务会顺利运行几天,但有时示例方法 importaData() 不会终止,因此 importDataTask() 不会再次调用,一切都会被阻塞,直到我重新启动应用程序.

问题是:有没有一种可行的方法来确保一个方法不会被无限期地阻塞(比如等待资源,或者其他什么)?

首先,当然。如果进程被阻塞,有很多可行的方法可以提醒你,比如log/message/email,嵌入在你的代码中。

其次,就看你要不要屏蔽了。如果阻塞不是你的意图,新线程或超时可能是你的选择。

The question is: is there a feasibile method to be sure that a method will not be indefinitely blocked (waybe waiting for a resource, or something else)?

如果无法以精确的规则间隔计划调度,您可能不应该使用固定延迟,而是使用两个条件:延迟 + 最后执行完成。
您可以安排一个任务来检查是否满足这两个条件,如果满足,您 运行 进行重要处理。否则,它等待下一个调度。
这样,您就不会被阻止。如果任务超过固定延迟,您可以等待一段时间。如果这是一个问题,因为经常超过固定延迟,您可能不应该使用固定延迟,或者您应该敏感地增加它以使其不那么常见。

举个例子(不用编辑器写的。如有错误请见谅):

private boolean isLastImportDataTaskFinished;

@Scheduled(fixedDelay = 300000)
 public void importDataTaskManager(){
    if (isLastImportDataTaskFinished()){
        new Thread(new ImportantDataProcessing())).start();           
    }
    else{
        // log the problem if you want
    }
}

 private isLastImportDataTaskFinished(){
   // to retrieve this information, you can do as you want : use a variable 
   //  in this class or a data in database,file...
   // here a simple implementation 
   return isLastImportDataTaskFinished;
 }

可运行class:

 public class ImportantDataProcessing implements Runnable{
   public void run(){       
      importData(); //db calls, file manipulations, etc..    
  }
}

评论:

But if I run it as a thread how can I kill it if I find it's exceeding the time limit since I don't have any reference to it (in the idea of using a second task to determine the stuck state)?

您可以使用 ExecutorService(您对此有疑问:How to timeout a thread)。

这是一个非常简单的例子:

ExecutorService executor = Executors.newSingleThreadExecutor();
Future future = executor.submit(new ImportantDataProcessing());
try {
    future.get(100, TimeUnit.SECONDS);
}
catch (InterruptedException e) {
    e.printStackTrace();
}
catch (ExecutionException e) {
    e.printStackTrace();
}
catch (TimeoutException e) {
    // the timeout to handle but other exceptions should be handled :)  
    e.printStackTrace();
}
executor.shutdown();

如果 ImportantDataProcessing 处理可能会返回有趣的信息,您可以使用任务而不是 运行nable 实例来键入未来。