[英]Run a script for a specified period of time in 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
限制內完成,則將返回該值(此處為響應future.get()
方法的Integer
對象)
而且,此批處理是異步的 (如果您未顯式調用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()
位置)中給出執行異常,但longRunningTask
仍將顯示“ Sleep Completed. Task Completed.
Sleep Completed. Task Completed.
完成10秒鍾的睡眠后。
如果您仔細注意, longRunnigThread
永遠不會中斷(不會進入catch塊),因此可以正常繼續,但是主線程在get()
上get()
異常。
解決方法/解決方案:
使用ExecutorService
並與此Exceutor
一起提交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;
}
使用這種方法,它不會完成發生超時的任務(您不會看到Sleep completed. Task completed.
在日志中..),並且會看到longRunningTask
線程中exception occurred
了exception occurred
(由於myWorker.shutdown
引起的中斷) myWorker.shutdown
)。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.