Java併發程式設計實戰--FutureTask

衣舞晨風發表於2017-05-24

FutureTask也可以用作閉鎖。(FutureTask實現了Future語義,表示一種抽象的可生成結果的計算。FutureTask表示的計算是通過Callable來實現的,相當於一種可生成結果的Runnable,並且可以處於以下3種狀態:等待執行(Waiting to run),正在執行(Running)和執行完成(Completed)。”執行完成”表示計算的所有可能結束方式,包括正常結束、由於取消而結束和由於異常而結束等。當FutureTask進入完成狀態後,它會停止在這個狀態上。

Future.get的行為取決於任務的狀態。如果任務已經完成,那麼get會立即返回結果,否則get將阻塞直到任務進入完成狀態,然後返回結果或者丟擲異常。FutureTask將計算結果從執行計算的執行緒到獲取這個結果的執行緒,而FutureTask的規範確保了這種傳遞過程能實現結果的安全釋出。

FutureTask在Executor框架中表示非同步任務,此外還可以用來表示一些時間較長的計算,這些計算可以在使用計算結果之前啟動。

public class Preloader {
    ProductInfo loadProductInfo() throws DataLoadException, InterruptedException {
        System.out.println("loadProductInfo start");
        Thread.sleep(1000 * 10);
        System.out.println("loadProductInfo end");
        return null;
    }

    private final FutureTask<ProductInfo> future =
            new FutureTask<>(() -> loadProductInfo());
    private final Thread thread = new Thread(future);

    public void start() {
        thread.start();
        System.out.println("start");
    }

    public ProductInfo get()
            throws DataLoadException, InterruptedException {
        try {
            System.out.println("get start");
            ProductInfo per = future.get();
            System.out.println("get end");
            return per;
        } catch (ExecutionException e) {
            Throwable cause = e.getCause();
            if (cause instanceof DataLoadException)
                throw (DataLoadException) cause;
            else {
               // throw LaunderThrowable.launderThrowable(cause);
                return null;
            }
        }
    }

    interface ProductInfo {
    }
}

class DataLoadException extends Exception {
}

Preloader建立了一個FutureTask,其中包含從資料庫載入產品資訊的任務,以及一個執行運算的執行緒。由於在建構函式或靜態初始化方法中啟動執行緒並不是一種好方法,因此提供了一個start方法來啟動執行緒。當程式雖有需要ProductInfo時,可以呼叫get方法,如果資料已經載入,那麼將返回這些資料,否則將等待載入完成後再返回。

Callable表示的任務可以丟擲受檢查的或未受檢查的異常,並且任何程式碼都可能丟擲一個Error。無論任務程式碼丟擲什麼異常,都會被封裝到一個ExecutionException中,並在Future.get中被重新丟擲。這將使呼叫get的程式碼變得複雜,因為它不僅需要處理可能出現的ExecutionException(以及未檢查的CancellationException),而且還由於ExecutionException是作為一個Throwable類返回的,因此處理起來並不容易。

Preloader preloader=new Preloader();
preloader.start();
preloader.get();

輸出
start
get start
loadProductInfo start
loadProductInfo end
get end

java併發程式設計實戰pdf及案例原始碼下載:
http://download.csdn.net/detail/xunzaosiyecao/9851028

作者:jiankunking 出處:http://blog.csdn.net/jiankunking

相關文章