譯文:http://www.importnew.com/16149.htmlhtml
原文:http://www.javacodegeeks.com/2014/12/asynchronous-timeouts-with-completablefuture.htmljava
CompletableFuture
Future.get()
方法會阻塞線程,一直阻塞,直到其所對應的任務完成或由於異常退出。在不恰當的地方調用此方法會由於線程阻塞而下降系統響應度。就像文中提到的。Future.get(long, TimeUnit)
能夠必定的時間內超時退出,而不會像前一個方法那樣一直阻塞線程。可是這對系統響應性的改進是治標不治本。CompletableFuture
,可用經過 CompletableFuture<Void> thenAccept(Consumer<? super T> action)
方法異步觸發 send(Response)
方法。這時 serve()
方法會很快結束。而當 responseFuture
所對應的任務完成時,send(Response)
方法便會被調用,其執行線程同 responseFuture
所對應的任務的執行線程相同。responseFuture
所對應任務 (Runnable
or Callable
) 裏面調用 send(Response)
方法。各類在實際工做中可能會遇到的問題暫且不說。只說兩點:
responseFuture
所對應任務是不可修改的,好比調用自第三方模塊responseFuture
所對應的任務中去調用 send(Response)
方法代表的含義是後者的功能從屬於前者。這可能從業務角度上看是不合理的。即在本例中,responseFuture
所對應的任務和 send(Response)
方法在業務角度講是屬於同一級的。違反這一點會對代碼可讀性和可維護性不利。thenAccept
和 thenAcceptAsync
thenAccept(Consumer<? super T> action)
這個方法的命名採用了相似 Promise 的命名風格。若是把這個方法命名爲 addListener
會更容易理解,可是命名爲 addListener
不能體現出 thenAccept
能返回 CompletableFuture
從而造成鏈式調用的特色。CompletableFuture
還有一個方法 thenAcceptAsync(Consumer<? super T> action, Executor executor)
,能夠爲任務指定線程池,從而隔離不一樣任務的執行線程,避免相互影響。(吐槽一下,CompletableFuture
定義的方法實在太多了)thenAccept
方法調用 send
方法實現了異步編程,帶來了好處,但同時也帶來了不少問題。第一個問題即是異常的處理。在使用 Java 寫併發程序的時候要注意異常處理,這是一個從 Java 1.4 開始就須要注意的問題。有經驗的開發人員都知道 Java 的 Thread
有兩個和異常處理相關的方法,分別是 setDefaultUncaughtExceptionHandler
和 setUncaughtExceptionHandler
。前者是靜態方法。這兩個方法是用來設置異常處理策略的。固然,一個更簡單的方法是在 send
裏捕獲和處理全部異常。若是你和你的公司容許大量無聊的重複代碼出現的話,這麼作是沒有問題的。UncaughtExceptionHandler
這兩種方法外,對於本例來講,還能夠經過 CompletableFuture<T> exceptionally(Function<Throwable,? extends T> fn)
方法來處理異常。exceptionally()
方法中的 Function
是用來處理 responseFuture
所對應任務拋出的異常Function
的返回值將做爲 thenAccept
方法的 Consumer
入參。在本例中就是 null
CompletableFuture
實現超時異常場景的方法是經過使用 CompletableFuture<Void> acceptEither(CompletionStage<? extends T> other, Consumer<? super T> action)
。這個方法的意思是 this CompletionStage
或 other CompletionStage
誰先完成,其結果就會做爲 Consumer<? super T> action
的入參。而後經過實現一個超時的 CompletionStage
CompletableFuture
另外一些方法。CompletableFuture
是一個提供了多種複雜異步功能的類。有時間最好能瞭解一下這個類的源代碼編程