CompletableFuture
創(chuàng)建
-
runAsync
使用
runAsync()
運(yùn)行異步計(jì)算 如果你想異步的運(yùn)行一個(gè)后臺(tái)任務(wù)并且不想改任務(wù)返回任務(wù)東西术唬,這時(shí)候可以使用CompletableFuture.runAsync()
方法设捐,它持有一個(gè)Runnable對(duì)象借浊,并返回CompletableFuture
。CompletableFuture<Void> runnable_task = CompletableFuture.runAsync(() -> System.out.println("Runnable task")).whenComplete((v, t) -> { //當(dāng)拋出異常的時(shí)候 if (t != null) { t.printStackTrace(); } }); s
-
supplyAsync:
使用
supplyAsync()
運(yùn)行一個(gè)異步任務(wù)并且返回結(jié)果 , 它持有supplier
并且返回CompletableFuture<T>
是通過(guò)調(diào)用 傳入的supplier取得的值的類型萝招。CompletableFuture<String> stringCompletableFuture = CompletableFuture.supplyAsync(() -> "HELLO").whenComplete((v, t) -> { try { TimeUnit.SECONDS.sleep(5); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("whenComplete" + v); }); System.out.println(stringCompletableFuture.get());
轉(zhuǎn)換&&消費(fèi)
-
thenApply&thenAccept:
thenApply接受一個(gè)Function接口(接受R返回T)類型參數(shù)蚂斤,并且繼續(xù)返回CompletableFuture<T>,對(duì)調(diào)用者CompletableFuture<?>進(jìn)行了轉(zhuǎn)換槐沼,注意與thenCompose區(qū)分橡淆,
thenAccept接受一個(gè)Comsumer(接受T無(wú)返回值)類型參數(shù),并且返回CompletableFuture<void>,可繼續(xù)進(jìn)行鏈?zhǔn)讲僮鳎?strong>消費(fèi)。
thenRun接受一個(gè)Runnable,該方法不能不能接收來(lái)自前面的參數(shù),通常用與鏈?zhǔn)降慕Y(jié)尾
CompletableFuture<String> stringCompletableFuture = CompletableFuture.supplyAsync(() -> "HELLO").whenComplete((v, t) -> { try { TimeUnit.SECONDS.sleep(5); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("whenComplete" + v); }); //thenApply接受一個(gè)Function接口(接受R返回T)類型參數(shù)母赵,并且繼續(xù)返回CompletableFuture<T> //thenAccept接受一個(gè)Comsumer(接受T無(wú)返回值)類型參數(shù),并且返回CompletableFuture<void>,可繼續(xù)進(jìn)行鏈?zhǔn)讲僮?//thenAccept接受一個(gè)Runnable,該方法不能不能接收來(lái)自前面的參數(shù),通常用與鏈?zhǔn)降慕Y(jié)尾 stringCompletableFuture.thenApply(str -> str + "World").thenAccept(System.out::println).thenRun(() -> System.out.println("Done"));
組合:
-
thenCompose
thenCompose()用來(lái)連接兩個(gè)CompletableFuture逸爵,是生成一個(gè)新的CompletableFuture,并且前一個(gè)Future.get()會(huì)成為thenCompose的參數(shù)/注意與thenApply的區(qū)分
private static void thenCompose() { CompletableFuture.supplyAsync(() -> { System.out.println("Start thenCompose 1"); try { TimeUnit.SECONDS.sleep(3); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("End thenCompose 1"); return "HELLO WORLD"; }).thenCompose(i -> CompletableFuture.supplyAsync(() -> { System.out.println("Start thenCompose 2"); try { TimeUnit.SECONDS.sleep(3); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("Start thenCompose 2"); return i.length(); })).whenComplete((i, t) -> System.out.println(i)); }
-
thenCombine:
combine可以用以接受一個(gè)新的Completable和一個(gè)BiFunction,調(diào)用者和傳入的CompletableFuture作為BiFunction的參數(shù),再返回一個(gè)CompletableFuture<T>,可繼續(xù)操作。
private static void thenCombine() { CompletableFuture.supplyAsync(() -> { System.out.println("start thenCombine 1"); try { TimeUnit.SECONDS.sleep(ThreadLocalRandom.current().nextInt(6)); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("end thenCombine 1"); return "12345"; }).thenCombine(CompletableFuture.supplyAsync(() -> { System.out.println("start thenCombine 2"); try { TimeUnit.SECONDS.sleep(ThreadLocalRandom.current().nextInt(6)); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("end thenCombine 2"); return "6789"; }), (i, j) -> i.length() > j.length()).whenComplete((b, t) -> System.out.println(b)); }
完成時(shí)處理:
-
whenComplete
接受一個(gè)調(diào)用者的future.get()以及可能出現(xiàn)的Throwable作為參數(shù),對(duì)結(jié)果進(jìn)行消費(fèi)BiConsumer
CompletableFuture.supplyAsync(() -> { System.out.println("Start work"); sleep(2); System.out.println("End work"); return "res"; }).whenComplete((r, t) -> System.out.println(r));
-
exceptionally
倘若出現(xiàn)異常接受異常并進(jìn)行處理:
CompletableFuture.supplyAsync(() -> { System.out.println("Start work"); //sleep(2); System.out.println("End work"); return "res"; }).whenComplete((r, t) -> { System.out.println(r); if (t == null) { System.out.println("No err"); } });
MORE API
-
thenAcceptBoth
該函數(shù)接受前面的future.get()作為h參數(shù)傳入BiConsumer,并接受本參數(shù)callable的future.get()作為w參數(shù)傳入BiConsumer
private static void acceptBoth() { CompletableFuture.supplyAsync(() -> { System.out.println("Start task1"); try { TimeUnit.SECONDS.sleep(10); } catch (InterruptedException e) { e.printStackTrace(); } return "Hello"; }).thenAcceptBoth( //該函數(shù)接受前面的future.get()作為h參數(shù)傳入BiConsumer,并接受本參數(shù)callable的future.get()作為w參數(shù)傳入BiConsumer CompletableFuture.supplyAsync(() -> "World"), (h, w) -> System.out.println(h + "-----" + w)); }
-
acceptEither
取先完成的結(jié)果.但是沒(méi)完成的任務(wù)也將繼續(xù)執(zhí)行
private static void acceptEither() { CompletableFuture.supplyAsync(() -> { System.out.println("Start Either1"); try { TimeUnit.SECONDS.sleep(10); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("End Either2"); return "Either1"; }).acceptEither(CompletableFuture.supplyAsync(() -> { System.out.println("Start Either2"); try { TimeUnit.SECONDS.sleep(ThreadLocalRandom.current().nextInt(5)); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("End Either2"); return "Either2"; }), i -> System.out.println("Final result " + i)); }
-
runAfterBoth
執(zhí)行完畢后調(diào)用Runnable,不消費(fèi)
private static void runAfterBoth() { CompletableFuture.supplyAsync(() -> { System.out.println("start RunAfterBoth 1"); try { TimeUnit.SECONDS.sleep(ThreadLocalRandom.current().nextInt(6)); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("end RunAfterBoth 1"); return "Task 1 Result"; }).runAfterBoth(CompletableFuture.supplyAsync(() -> { System.out.println("start RunAfterBoth 2"); try { TimeUnit.SECONDS.sleep(ThreadLocalRandom.current().nextInt(5)); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("end RunAfterBoth 2"); return "Task 2 Result"; }), () -> System.out.println("Done")); }
-
getNow
在調(diào)用該方法時(shí)凹嘲,如果已經(jīng)CompleFuture已經(jīng)計(jì)算完成师倔,則返回future.get()的內(nèi)容,否者直接返回該方法的參數(shù)值(缺省)周蹭。
private static void getNow() throws InterruptedException { CompletableFuture<String> stringCompletableFuture = CompletableFuture.supplyAsync(() -> { try { TimeUnit.SECONDS.sleep(2); } catch (InterruptedException e) { e.printStackTrace(); } return "Hello"; }); String now = stringCompletableFuture.getNow("NOWWWWWWWWWWWWWWWWWWWWWWWw"); System.out.println(now); //output NOWWWWWWWWWWWWWWWWWWWWWWWw TimeUnit.SECONDS.sleep(3); now = stringCompletableFuture.getNow("NOWWWWWWWWWWWWWWWWWWWWWWWw"); System.out.println(now); //output Hello }
-
complete
類似于getNow方法趋艘,返回true的時(shí)候說(shuō)明CompletableFuture以及執(zhí)行完畢,該方法無(wú)效凶朗,返回false的時(shí)候瓷胧,說(shuō)明該方法設(shè)值成功,CompletableFuture尚未執(zhí)行完畢棚愤,調(diào)用future.get()將返回complete的參數(shù)值:
private static void complete() throws InterruptedException, ExecutionException { CompletableFuture<String> stringCompletableFuture = CompletableFuture.supplyAsync(() -> { try { TimeUnit.SECONDS.sleep(2); } catch (InterruptedException e) { e.printStackTrace(); } return "World"; }); //通過(guò)注釋該行來(lái)進(jìn)行兩種情況的測(cè)試 TimeUnit.SECONDS.sleep(3); stringCompletableFuture.complete("HELLO"); System.out.println(stringCompletableFuture.get()); }
-
join
- 用法跟get一樣阻塞調(diào)用但是join不會(huì)拋出異常