多線程Callable+Future和CompletableFuture

一. Future

JDK 5引入了Future模式。Future接口是Java多線程Future模式的實現(xiàn),在java.util.concurrent包中,可以來進行異步計算。

Future模式是多線程設(shè)計常用的一種設(shè)計模式。Future模式可以理解成:我有一個任務(wù),提交給了Future,F(xiàn)uture替我完成這個任務(wù)。期間我自己可以去做任何想做的事情。一段時間之后,我就便可以從Future那兒取出結(jié)果。

Future的接口很簡單,只有五個方法。

Future接口的方法介紹如下:

boolean cancel (boolean mayInterruptIfRunning) 取消任務(wù)的執(zhí)行。參數(shù)指定是否立即中斷任務(wù)執(zhí)行,或者等等任務(wù)結(jié)束

boolean isCancelled () 任務(wù)是否已經(jīng)取消,任務(wù)正常完成前將其取消,則返回 true

boolean isDone () 任務(wù)是否已經(jīng)完成。需要注意的是如果任務(wù)正常終止、異?;蛉∠紝⒎祷豻rue

V get () throws InterruptedException, ExecutionException? 等待任務(wù)執(zhí)行結(jié)束,然后獲得V類型的結(jié)果。InterruptedException 線程被中斷異常, ExecutionException任務(wù)執(zhí)行異常,如果任務(wù)被取消,還會拋出CancellationException

V get (long timeout, TimeUnit unit) throws InterruptedException, ExecutionException, TimeoutException 同上面的get功能一樣,多了設(shè)置超時時間。參數(shù)timeout指定超時時間,uint指定時間的單位,在枚舉類TimeUnit中有相關(guān)的定義。如果計 算超時,將拋出TimeoutException

一般情況下,我們會結(jié)合Callable和Future一起使用,通過ExecutorService的submit方法執(zhí)行Callable,并返回Future。

future


callable

比起future.get(),其實更推薦使用get (long timeout, TimeUnit unit) 方法,設(shè)置了超時時間可以防止程序無限制的等待future的結(jié)果。

二. CompletableFuture介紹

2.1 Future模式的缺點

Future雖然可以實現(xiàn)獲取異步執(zhí)行結(jié)果的需求,但是它沒有提供通知的機制,我們無法得知Future什么時候完成。

要么使用阻塞,在future.get()的地方等待future返回的結(jié)果,這時又變成同步操作。要么使用isDone()輪詢地判斷Future是否完成,這樣會耗費CPU的資源。

2.2 CompletableFuture介紹

Netty、Guava分別擴展了Java 的 Future 接口,方便異步編程。

Java 8新增的CompletableFuture類正是吸收了所有Google Guava中ListenableFuture和SettableFuture的特征,還提供了其它強大的功能,讓Java擁有了完整的非阻塞編程模型:Future、Promise 和 Callback(在Java8之前,只有無Callback 的Future)。

CompletableFuture能夠?qū)⒒卣{(diào)放到與任務(wù)不同的線程中執(zhí)行,也能將回調(diào)作為繼續(xù)執(zhí)行的同步函數(shù),在與任務(wù)相同的線程中執(zhí)行。它避免了傳統(tǒng)回調(diào)最大的問題,那就是能夠?qū)⒖刂屏鞣蛛x到不同的事件處理器中。

CompletableFuture彌補了Future模式的缺點。在異步的任務(wù)完成后,需要用其結(jié)果繼續(xù)操作時,無需等待??梢灾苯油ㄟ^thenAccept、thenApply、thenCompose等方式將前面異步處理的結(jié)果交給另外一個異步事件處理線程來處理。

三. CompletableFuture特性

3.1 CompletableFuture的靜態(tài)工廠方法

runAsync 和 supplyAsync 方法的區(qū)別是runAsync返回的CompletableFuture是沒有返回值的。


而supplyAsync返回的CompletableFuture是由返回值的,下面的代碼打印了future的返回值。

3.2 Completable


future.get()在等待執(zhí)行結(jié)果時,程序會一直block,如果此時調(diào)用complete(T t)會立即執(zhí)行。

可以看到future調(diào)用complete(T t)會立即執(zhí)行。但是complete(T t)只能調(diào)用一次,后續(xù)的重復調(diào)用會失效。

如果future已經(jīng)執(zhí)行完畢能夠返回結(jié)果,此時再調(diào)用complete(T t)則會無效。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容