Java如何實現任務超時處理


任務超時處理是比較常見的需求,比如在進行一些比較耗時的操作(如網絡請求)或者在占用一些比較寶貴的資源(如數據庫連接)時,我們通常需要給這些操作設置一個超時時間,當執行時長超過設置的閾值的時候,就終止操作並回收資源。Java中對超時任務的處理有兩種方式:一種是基於異步任務結果的超時獲取,一種則是使用延時任務來終止超時操作。下文將詳細說明。

 

一、基於異步任務結果的超時獲取

基於異步任務結果的獲取通常是跟線程池一起使用的,我們向線程池提交任務時會返回一個Future對象,在調用Future的get方法時,可以設置一個超時時間,如果超過設置的時間任務還沒結束,就拋出異常。接下來看代碼:

public class FutureDemo {

    static ExecutorService executorService= Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors()*2);

    public static void main(String[] args) {
        Future<String> future = executorService.submit(new Callable<String>() {
            @Override
            public String call() {
                try {
                    TimeUnit.SECONDS.sleep(10);
                } catch (InterruptedException e) {
                    System.out.println("任務被中斷。");
                }
                return  "OK";
            }
        });
        try {
            String result = future.get(2, TimeUnit.SECONDS);
        } catch (InterruptedException |ExecutionException | TimeoutException e) {
            future.cancel(true);
            System.out.println("任務超時。");
        }finally {
            System.out.println("清理資源。");
        }
    }
}

 

運行代碼,輸出如下:

二、使用延時任務來終止超時操作

還有一種實現任務超時處理的思路是在提交任務之前先設置一個定時器,這個定時器會在設置的時間間隔之后去取消任務。當然如果任務在規定的時間內完成了,要記得取消定時器。首先來看一下我們的工作線程:

public class RunningTask  {

    private volatile boolean isStop;

    public void stop(){
        this.isStop=true;
    }

    public void doing() {
        int i=1;
        while (!isStop){
            try {
                TimeUnit.SECONDS.sleep(1);
            } catch (InterruptedException e) {

            }
        }
        System.out.println("任務被中斷。");
    }
}

 

這個工作線程每隔一秒鍾會去檢查下isStop變量,因此我們可以通過isStop變量來取消任務。至於取消任務的邏輯我們放在了定時器里面,代碼如下:

public class CancelTask implements Runnable {

    private RunningTask runningTask;

    public CancelTask(RunningTask runningTask) {
        this.runningTask = runningTask;
    }

    @Override
    public void run() {
        runningTask.stop();
    }
}

 

可以看到,該定時器的作用就是在一定的時間之后去中斷工作線程的運行。接下來測試一下:

public class ScheduleDemo {

    static ScheduledExecutorService executorService= Executors.newScheduledThreadPool(Runtime.getRuntime().availableProcessors()*2);

    public static void main(String[] args) {
        RunningTask runningTask=new RunningTask();
        ScheduledFuture<?> scheduledFuture = executorService.schedule(new CancelTask(runningTask), 3, TimeUnit.SECONDS);
        runningTask.doing();
        if(!scheduledFuture.isDone()){
            scheduledFuture.cancel(true);
        }
    }
}

 

運行結果如下:

可以看到,任務在超時之后也可以被取消。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM