依賴單個任務完成(thenRun):單個CompletionStage任務執行完成回撥action處理,即執行action回撥方法無引數,回撥處理結果也無返回值。
```
// 上一個CompletionStage任務執行完成後直接回調action處理,無返回值
public CompletionStage thenRun(Runnable action);
// 同上,使用預設執行緒池執行action處理
public CompletionStage thenRunAsync(Runnable action);
// 同上,使用自定義執行緒池執行action處理
public CompletionStage thenRunAsync(Runnable action, Executor executor);
// ====================================demo華麗分割線============================================
CompletableFuture.runAsync(() -> {
// TODO
}).thenRunAsync(() -> {
log.info("this is thenRunAsync"); // 輸出結果:this is thenRunAsync
}).join();
```
依賴兩個任務都完成(runAfterBoth):兩個CompletionStage任務併發執行,必須兩個任務都完成才執行action回撥處理,即執行action回撥方法無引數,回撥處理結果也無返回值。
```
// 原理同3.1的thenAcceptBoth,只不過runAfterBoth的action回撥處理不接收引數且任務執行完成無返回值
public CompletionStage runAfterBoth(CompletionStage<?> other, Runnable action);
// 同上,使用預設執行緒池執行action處理
public CompletionStage runAfterBothAsync(CompletionStage<?> other, Runnable action);
// 同上,使用自定義執行緒池執行action處理
public CompletionStage runAfterBothAsync(CompletionStage<?> other, Runnable action, Executor executor);
// ====================================demo華麗分割線============================================
CompletableFuture cf331 = CompletableFuture.supplyAsync(() -> "this is supplyAsync cf331");
CompletableFuture cf332 = CompletableFuture.supplyAsync(() -> "this is supplyAsync cf332");
cf331.runAfterBoth(cf332, () -> {
log.info("this is runAfterBoth");
}).join();
// 輸出結果:this is runAfterBoth
```
依賴兩個任務中的任何一個完成(runAfterEither):兩個CompletionStage任務併發執行,只需其中任何一個任務完成即可回撥action處理,即執行action回撥方法無引數,回撥處理結果也無返回值。
```
public CompletionStage runAfterEither(CompletionStage<?> other, Runnable action);
public CompletionStage runAfterEitherAsync(CompletionStage<?> other, Runnable action);
public CompletionStage runAfterEitherAsync(CompletionStage<?> other, Runnable action, Executor executor);
// ====================================demo華麗分割線============================================
CompletableFuture cf331 = CompletableFuture.supplyAsync(() -> "this is supplyAsync cf331");
CompletableFuture cf332 = CompletableFuture.supplyAsync(() -> "this is supplyAsync cf332");
cf331.runAfterEitherAsync(cf332, () -> {
log.info("this is runAfterEitherAsync");
}).join();
// 輸出結果:this is runAfterEitherAsync
```
3.4 組合型別
thenCompose:存在先後關係的兩個任務進行序列組合,由第一個CompletionStage任務執行結果作為引數傳遞給第二個CompletionStage任務,最終返回第二個CompletionStage。
```
public CompletionStage thenCompose(Function<? super T, ? extends CompletionStage> fn);
public CompletionStage thenComposeAsync(Function<? super T, ? extends CompletionStage> fn);
public CompletionStage thenComposeAsync(Function<? super T, ? extends CompletionStage> fn, Executor executor);
// ====================================demo華麗分割線============================================
CompletableFuture supplyFuture = CompletableFuture.supplyAsync(() -> {
return "this is supplyAsync";
});
CompletableFuture thenComposeFuture = supplyFuture.thenComposeAsync((r) -> {
return CompletableFuture.supplyAsync(() -> {
return r + " and this is thenComposeAsync";
});
});
log.info(thenComposeFuture.join());
// 輸出結果:this is supplyAsync and this is thenComposeAsync
```
任務完成事件(whenComplete):結果無返回值,若出現異常執行完whenComplete回撥處理完成後將中斷主執行緒的執行。
```
// 1.whenComplete回撥函式中Throwable物件不對空代表出現異常,為空則表示無異常
public CompletionStage whenComplete(BiConsumer<? super T, ? super Throwable> action);
public CompletionStage whenCompleteAsync(BiConsumer<? super T, ? super Throwable> action);
public CompletionStage whenCompleteAsync(BiConsumer<? super T, ? super Throwable> action, Executor executor);
// ====================================demo華麗分割線============================================
CompletableFuture whenCompleteFufute = CompletableFuture.supplyAsync(() -> {
int a = 0;
int b = 100 / a;
return "this is supplyAsync normal";
}).whenCompleteAsync((r, th) -> {
if (th != null) {
log.error("this is whenCompleteAsync error");
}
else {
log.info("this is whenCompleteAsync success");
}
});
log.info(whenCompleteFufute.join()); // 輸出結果:this is whenCompleteAsync error
```