CompletableFuture基本用法

異步計算

  • 所謂異步調用其實就是實現一個可無需等待被調用函數的返回值而讓操做繼續運行的方法。在 Java 語言中,簡單的講就是另啓一個線程來完成調用中的部分計算,使調用繼續運行或返回,而不須要等待計算結果。但調用者仍須要取線程的計算結果。編程

  • JDK5新增了Future接口,用於描述一個異步計算的結果。雖然 Future 以及相關使用方法提供了異步執行任務的能力,可是對於結果的獲取倒是很不方便,只能經過阻塞或者輪詢的方式獲得任務的結果。阻塞的方式顯然和咱們的異步編程的初衷相違背,輪詢的方式又會耗費無謂的 CPU 資源,並且也不能及時地獲得計算結果。多線程

  • 之前咱們獲取一個異步任務的結果多是這樣寫的

  

Future 接口的侷限性

Future接口能夠構建異步應用,但依然有其侷限性。它很難直接表述多個Future 結果之間的依賴性。實際開發中,咱們常常須要達成如下目的:異步

  1. 將多個異步計算的結果合併成一個函數式編程

  2. 等待Future集合中的全部任務都完成異步編程

  3. Future完成事件(即,任務完成之後觸發執行動做)函數

  4. 。。。

函數式編程

CompletionStage

  • CompletionStage表明異步計算過程當中的某一個階段,一個階段完成之後可能會觸發另一個階段spa

  • 一個階段的計算執行能夠是一個Function,Consumer或者Runnable。好比:stage.thenApply(x -> square(x)).thenAccept(x -> System.out.print(x)).thenRun(() -> System.out.println())線程

  • 一個階段的執行多是被單個階段的完成觸發,也多是由多個階段一塊兒觸發3d

CompletableFuture

  • 在Java8中,CompletableFuture提供了很是強大的Future的擴展功能,能夠幫助咱們簡化異步編程的複雜性,而且提供了函數式編程的能力,能夠經過回調的方式處理計算結果,也提供了轉換和組合 CompletableFuture 的方法。
  • 它可能表明一個明確完成的Future,也有可能表明一個完成階段( CompletionStage ),它支持在計算完成之後觸發一些函數或執行某些動做。
  • 它實現了Future和CompletionStage接口

  

CompletableFuture基本用法

建立CompletableFuture

thenApply

當前階段正常完成之後執行,並且當前階段的執行的結果會做爲下一階段的輸入參數。thenApplyAsync默認是異步執行的。這裏所謂的異步指的是不在當前線程內執行。blog

thenApply至關於回調函數(callback)


 

thenAccept與thenRun

  • 能夠看到,thenAccept和thenRun都是無返回值的。若是說thenApply是不停的輸入輸出的進行生產,那麼thenAccept和thenRun就是在進行消耗。它們是整個計算的最後兩個階段。
  • 一樣是執行指定的動做,一樣是消耗,兩者也有區別:

    • thenAccept接收上一階段的輸出做爲本階段的輸入   

    • thenRun根本不關心前一階段的輸出,根本不不關心前一階段的計算結果,由於它不須要輸入參數

thenCombine整合兩個計算結果

例如,此階段與其它階段一塊兒完成,進而觸發下一階段:

whenComplete

 

最後,舉個栗子:

事實上,若是每一個操做都很簡單的話(好比:上面的例子中按照id去查)沒有必要用這種多線程異步的方式,由於建立線程還須要時間,還不如直接同步執行來得快。

事實證實,只有當每一個操做很複雜須要花費相對很長的時間(好比,調用多個其它的系統的接口;好比,商品詳情頁面這種須要從多個系統中查數據顯示的)的時候用CompletableFuture才合適,否則區別真的不大,還不如順序同步執行。

相關文章
相關標籤/搜索