我有一个我想运行的java代码。如果作业没有在 2 小时内完成,那么它应该被自动终止(基本上是某种定时批处理)。
如何用Java实现这一点?
最佳答案
如果您使用的是 Java 9 或更高版本,您可以执行以下超时批处理:-
CompletableFuture<Integer> future = CompletableFuture.supplyAsync(this::longRunningTask)
.orTimeout(2, TimeUnit.SECONDS);
future.get(); // j.u.c.ExecutionException after waiting for 2 second
如果在timeout
限制内完成,它将返回值(这里是一个Integer
对象来响应future.get()
方法)
并且,此批处理是异步(如果您不显式调用 get 方法。)
注意:这不会阻止线程完成任务,它只是在主线程中完成一个带有超时异常的 future,以便主线程可以继续。后台任务/线程仍在继续完成。 (看@Andreas评论)
一些示例:-
final CompletableFuture<Void> future =
CompletableFuture.supplyAsync(this::longRunningTask)
.orTimeout(2, TimeUnit.SECONDS);
future.get(); // j.u.c.ExecutionException after waiting for 2 second
还有longRunningTask()
:-
private Void longRunningTask(){
log.info("Thread name" + Thread.currentThread().getName());
try {
log.info("Going to sleep for 10 sec...");
Thread.sleep(10*1000);
log.info("Sleep Completed. Task Completed.");
} catch (InterruptedException e) {
log.info("Exception Occurred");
}
finally{
log.info("Final Cleanup in progress.");
}
log.info("Finishing the long task.");
return null;
}
如果你运行上面的代码,它会在主线程(其中调用 future.get()
)中给出执行异常,但 longRunningTask
仍然会打印 sleep 完成。任务已完成。
完成 10 秒 sleep 后。
如果您仔细观察,longRunnigThread
永远不会被中断(不会进入 catch block ),因此会正常继续,但主线程在 get()
上出现异常。
解决方法/解决方案:
使用ExecutorService
并使用该Executor
提交longRunnigTask future,如果超时,则关闭执行器,否则,在get()成功后关闭
如果没有超时异常。
示例:
ExecutorService myWorkers = Executors.newFixedThreadPool(1);
final CompletableFuture<Void> longTask =
CompletableFuture.supplyAsync(this::longRunningTask, myWorkers)
.orTimeout(2, TimeUnit.SECONDS);
try {
longTask.get();
} catch (InterruptedException | ExecutionException e) {
log.info("EE... Kill the executor thread/s.");
myWorkers.shutdownNow(); // this will interrupt the thread, catch the IntrExcep in thread and return the execution there
}
以及稍作修改的longRunnigTask
private Void longRunningTask(){
log.info("Thread name" + Thread.currentThread().getName());
try {
log.info("Going to sleep for 10 sec...");
Thread.sleep(10*1000);
log.info("Sleep Completed. Task Completed.");
} catch (InterruptedException e) {
log.info("Exception Occurred");
return null; // this will finish the thread exce releasing all locking resources. Can be GCed then.
}
finally{
log.info("Final Cleanup in progress.");
}
log.info("Finishing the long task.");
return null;
}
使用这种方法,如果发生超时,它将无法完成任务(您不会在日志中看到 sleep 已完成。任务已完成。
..),并且会看到,
(由于 longRunningTask
线程发生异常myWorker.shutdown
导致中断)。
关于java - 在 Java 中运行脚本指定的时间段,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57950990/