標籤:main 通過 ring 工作 cancel 如何 ble nbsp Fix
任務逾時處理是比較常見的需求,比如在進行一些比較耗時的操作(如網路請求)或者在佔用一些比較寶貴的資源(如資料庫連接)時,我們通常需要給這些操作設定一個逾時時間,當執行時間長度超過設定的閾值的時候,就終止操作並回收資源。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); } }}
運行結果如下:
可以看到,任務在逾時之後也可以被取消。
Java如何?任務逾時處理