從JDK 8開始把将,在Concurrent包中提供了一個(gè)強(qiáng)大的異步編程工具CompletableFuture秸弛。在JDK8之前递览,異步編程可以通過(guò)線程池和Future來(lái)實(shí)現(xiàn)瞳腌,但功能還不夠強(qiáng)大。
1.用法
public static void main(String[] args) throws ExecutionException, InterruptedException {
CompletableFuture<String> future = new CompletableFuture<>();
new Thread(() -> {
try {Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
future.complete("hello world");
}).start();
System.out.println("獲取結(jié)果中儿捧。。菲盾。");
String result = future.get();
System.out.println("獲取的結(jié)果:" + result); }
CompletableFuture實(shí)現(xiàn)了Future接口,所以它也具有Future的特性:調(diào)用get()方法會(huì)阻塞在那诡挂,直到結(jié)果返回临谱。
另外1個(gè)線程調(diào)用complete方法完成該Future,則所有阻塞在get()方法的線程都將獲得返回結(jié)果城豁。
1.1 runAsync與supplyAsync
- CompletableFuture.runAsync(...)傳入的是一個(gè)Runnable接口
- supplyAsync(Supplier)
區(qū)別:supplyAsync任務(wù)有返回值唱星。沒有返回值的任務(wù)剖膳,提交的是Runnable,返回的是CompletableFuture<Void>甸饱;有返回值的任務(wù)叹话,提交的是 Supplier墩瞳,返回的是
CompletableFuture<String>。Supplier和前面的Callable很相似热凹。
1.2 thenRun泪电、thenAccept和thenApply
對(duì)于 Future,在提交任務(wù)之后碟渺,只能調(diào)用 get()等結(jié)果返回苫拍;但對(duì)于 CompletableFuture,可以在結(jié)果上面再加一個(gè)callback绒极,當(dāng)?shù)玫浇Y(jié)果之后,再接著執(zhí)行callback伏社。
- CompletableFuture.supplyAsync(....).thenRun();
- CompletableFuture.supplyAsync(....).thenAccept((param)->....);
- CompletableFuture.supplyAsync(....).thenApply(new Function<String, Integer>()...);
- thenRun后面跟的是一個(gè)無(wú)參數(shù)摘昌、無(wú)返回值的方法高蜂,即Runnable,所以最終的返回值是CompletableFuture<Void>類型稿饰。
- thenAccept后面跟的是一個(gè)有參數(shù)喉镰、無(wú)返回值的方法惭笑,稱為Consumer,返回值也是CompletableFuture<Void>類型捺宗。顧名思義川蒙,只進(jìn)不出,所以稱為Consumer昼牛;前面的Supplier匾嘱,是無(wú)參數(shù)早抠,有返回值撬讽,只出不進(jìn)悬垃,和Consumer剛好相反尝蠕。
- thenApply 后面跟的是一個(gè)有參數(shù)看彼、有返回值的方法囚聚,稱為Function。返回值是CompletableFuture<String>類型
1.3thenCompose茁计、thenCombine
thenCompose
thenApply接收的是一個(gè)Function星压,但是這個(gè)Function的返回值是一個(gè)通常的基本數(shù)據(jù)類型或一個(gè)對(duì)象鬼譬,而不是另外一個(gè) CompletableFuture。如果 Function 的返回值也是一個(gè)CompletableFuture优质,就會(huì)出現(xiàn)嵌套的CompletableFuture盆赤。
如果希望返回值是一個(gè)非嵌套的CompletableFuture,可以使用thenCompose颤枪。
CompletableFuture.supplyAsync(new Supplier<T>({..})..thenCompose(new Function<String, CompletionStage<T>>(){...});
thenCombine
在2個(gè) CompletableFuture 完成之后淑际,把2個(gè)CompletableFuture的返回值傳進(jìn)去,再額外做一些事情盗胀。實(shí)例如下:
1.4任意個(gè)CompletableFuture的組合
- 上面的thenCompose和thenCombine只能組合2個(gè)CompletableFuture锄贼,而接下來(lái)的allOf 和anyOf 可以組合任意多個(gè)CompletableFuture。
- 兩個(gè)方法都是靜態(tài)方法浸策,參數(shù)是變長(zhǎng)的CompletableFuture的集合惹盼。其次,allOf和anyOf的區(qū)別蚯舱,前者是“與”掩蛤,后者是“或”。
- allOf需要所有的CompletableFuture 完成才返回凶掰,所以返回值是CompletableFuture<Void>類型懦窘,這是因?yàn)槊總€(gè)傳入的CompletableFuture的返回值都可能不同,所以組合的結(jié)果是無(wú)法用某種類型來(lái)表示的畅涂,索性返回Void類型道川。
- anyOf 的含義是只要有任意一個(gè) CompletableFuture 結(jié)束冒萄,就可以做接下來(lái)的事情,而無(wú)須像AllOf那樣帅戒,等待所有的CompletableFuture結(jié)束
1.5四種任務(wù)原型
runAsync 與 supplierAsync 是 CompletableFuture 的靜態(tài)方法逻住;而 thenAccept迎献、thenAsync、thenApply是CompletableFutre的成員方法扒秸。
因?yàn)槌跏嫉臅r(shí)候沒有CompletableFuture對(duì)象,也沒有參數(shù)可傳鸦采,所以提交的只能是Runnable或者Supplier,只能是靜態(tài)方法;