簡體   English   中英

在Java中運行腳本一段指定的時間

[英]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 occurredexception occurred (由於myWorker.shutdown引起的中斷) myWorker.shutdown )。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM