可贖回和未來

雖然 Runnable 提供了一種將程式碼包裝在不同執行緒中的方法,但它有一個限制,即它不能從執行中返回結果。從執行 Runnable 獲得一些返回值的唯一方法是將結果分配給在 Runnable 之外的範圍內可訪問的變數。

Callable 作為 Runnable 的同行在 Java 5 中引入。Callable 基本上是相同的,除了它有 call 方法而不是 runcall 方法具有返回結果的附加功能,並且還允許丟擲已檢查的異常。

可呼叫任務提交的結果*可*通過 Future 進行挖掘 ******

Future 可以被認為是包含 Callable 計算結果的各種容器。可呼叫的計算可以在另一個執行緒中繼續進行,任何嘗試點選 Future 的結果都將被阻止,並且只有在結果可用時才返回結果。

可呼叫介面

public interface Callable<V> {
    V call() throws Exception;
}

未來

interface Future<V> {
    V get();
    V get(long timeout, TimeUnit unit);
    boolean cancel(boolean mayInterruptIfRunning);
    boolean isCancelled();
    boolean isDone();
}

使用 Callable 和 Future 示例:

public static void main(String[] args) throws Exception {
    ExecutorService es = Executors.newSingleThreadExecutor();
          
    System.out.println("Time At Task Submission : " + new Date());
    Future<String> result = es.submit(new ComplexCalculator());
    // the call to Future.get() blocks until the result is available.So we are in for about a 10 sec wait now
    System.out.println("Result of Complex Calculation is : " + result.get());
    System.out.println("Time At the Point of Printing the Result : " + new Date());
}

我們的 Callable 執行冗長的計算

public class ComplexCalculator implements Callable<String> {

    @Override
    public String call() throws Exception {
        // just sleep for 10 secs to simulate a lengthy computation
        Thread.sleep(10000);            
        System.out.println("Result after a lengthy 10sec calculation");
        return "Complex Result"; // the result 
    }
}

輸出

Time At Task Submission : Thu Aug 04 15:05:15 EDT 2016
Result after a lengthy 10sec calculation
Result of Complex Calculation is : Complex Result
Time At the Point of Printing the Result : Thu Aug 04 15:05:25 EDT 2016

Future 上允許的其他操作

雖然 get() 是提取實際結果的方法,但 Future 已提供

  • get(long timeout, TimeUnit unit) 定義當前執行緒等待結果的最大時間段;
  • 要取消任務,請撥打 cancel(mayInterruptIfRunning)。標誌 mayInterrupt 表示如果任務已啟動並且正在執行,則應該中斷該任務;
  • 通過呼叫 isDone() 來檢查任務是否完成/完成;
  • 檢查冗長的任務是否被取消了。