java - 在 Java 中运行指定时间段的脚本
问题描述
我有一个要运行的 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 方法。)
注意:这不会阻止线程完成任务,它只是在主线程中完成一个带有超时异常的未来,以便主线程可以继续。后台任务/线程仍在继续完成。(看@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()
被调用的地方)中给出执行异常,但在完成 10 秒睡眠后longRunningTask
仍会打印。Sleep Completed. Task Completed.
如果你仔细注意到,longRunnigThread
它永远不会被中断(不会进入 catch 块)所以会正常继续,但主线程会在get()
.
解决方法/解决方案:
使用ExecutorService
并提交 longRunnigTask 未来Exceutor
,如果发生超时,关闭执行器,否则,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;
}
使用这种方法,它不会完成任务 inf 超时发生(您不会Sleep completed. Task completed.
在日志中看到..),并且会exception occurred
在longRunningTask
线程中看到(因为由 引起的中断myWorker.shutdown
)。
推荐阅读
- wordpress - 错误:应在 google 搜索控制台中指定“offers”、“review”或“aggregateRating”
- laravel - Laravel 自定义 CronJob 进行 15 天和 x 天的定时调度
- git - 如何使用配置或一些脚本自动处理 git push 到 DEV 分支
- css - 只有 CSS 才能在新选项卡中打开链接
- spring-boot - 为什么每次请求/响应都会更新“X-Auth-Token”?
- c# - XAMPP 一段时间后变得超级慢
- java - 无法在使用 java 的 selenium webdriver 中从 ChromeDriver 转换为 WebDriver,如何克服这个问题?
- unit-testing - Jest/Enzyme ReactNative 如何测试功能组件中的状态
- ios - 静止图像上带有动画的运动/移动效果
- r - 使用反应变量使用 plotly 绘制直方图