在Spring Web应用程序中,我有一个每五分钟调用一次的计划任务。
@Scheduled(fixedDelay = 300000)
public void importDataTask()
{
importData(); //db calls, file manipulations, etc..
}
通常情况下,任务会顺利运行数天,但有时会发生示例方法importaData()
不会终止,因此在重新启动应用程序之前,将不会再次调用importDataTask()
并阻止所有内容。< / p>
问题是:是否有一种可行的方法可以确保方法不会被无限期阻止(等待资源或其他东西)?
答案 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)
首先,确定。如果进程被阻止,有许多可行的方法可以提醒您,例如嵌入代码中的日志/消息/电子邮件。
其次,决定是否要阻止它。如果您不打算阻止,则可以选择新线程或超时。