如何确保@scheduled任务终止?

时间:2016-10-29 14:20:57

标签: java spring job-scheduling

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

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

通常情况下,任务会顺利运行数天,但有时会发生示例方法importaData()不会终止,因此在重新启动应用程序之前,将不会再次调用importDataTask()并阻止所有内容。< / p>

问题是:是否有一种可行的方法可以确保方法不会被无限期阻止(等待资源或其他东西)?

2 个答案:

答案 0 :(得分:1)

  

问题是:是否有可行的方法来确保方法   不会被无限期阻止(等待资源,或者   别的什么)?

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

这是一个例子(没有编辑的写作。对不起,如果有任何错误):

while loop and i < len(l):

Runnable类:

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

注释:

  

但是如果我把它作为一个线程运行,如果我发现它超过它我怎么能杀死它   因为我没有任何参考的时间限制(在...的想法   使用第二个任务来确定卡住状态)?

您可以使用ExecutorService(您在此处有一个问题:How to timeout a thread)。

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

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

如果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(); 处理可能返回有趣的信息,您可以使用任务而不是可运行的实例来键入未来。

答案 1 :(得分:0)

首先,确定。如果进程被阻止,有许多可行的方法可以提醒您,例如嵌入代码中的日志/消息/电子邮件。

其次,决定是否要阻止它。如果您不打算阻止,则可以选择新线程或超时。