CompletableFuture 是 Java 8 引入的一種用于處理異步程式設計的工具。它提供了一種非常靈活而且易于使用的方式來處理并發任務,能夠簡化代碼的編寫,并提高程式的性能。
CompletableFuture 類實作了 Future 和 CompletionStage 接口,是以可以用來表示一個異步計算的結果,還可以在計算完成後執行一些操作。下面将詳細介紹 CompletableFuture 的使用和一些常見的應用場景。
一、基本用法
1、建立 CompletableFuture 對象
CompletableFuture 可以通過以下方式進行建立:
CompletableFuture<T> future = new CompletableFuture<>();
2、執行異步任務
可以使用線程池執行異步任務,并設定任務執行完畢後的回調函數:
CompletableFuture<Void> future = CompletableFuture.runAsync(() -> {
// 異步任務的具體邏輯
}, executor);
這裡的 executor 是一個可選的參數,可以指定線程池,如果不指定,則使用預設的 ForkJoinPool 線程池。
3、擷取異步任務的結果
可以使用 get() 方法來擷取異步任務的結果,注意這是一個阻塞方法,會一直等待任務完成:
T result = future.get();
4、處理任務的執行結果
可以使用 thenAccept()、thenApply()、thenRun() 等方法對任務的執行結果進行處理,這些方法都接受一個回調函數作為參數,任務完成後會觸發回調函數的執行。
5、異常處理
可以使用 exceptionally() 方法來處理任務執行過程中出現的異常:
CompletableFuture<T> future = CompletableFuture.supplyAsync(() -> {
// 執行可能會抛出異常的代碼
}).exceptionally(ex -> {
// 異常處理邏輯
return defaultValue;
});
二、組合多個 CompletableFuture
1、thenCompose()
通過 thenCompose() 方法可以将兩個 CompletableFuture 對象串聯起來,将一個任務的結果作為另一個任務的輸入:
CompletableFuture<Integer> future1 = CompletableFuture.supplyAsync(() -> 10);
CompletableFuture<Integer> future2 = future1.thenCompose(result -> CompletableFuture.supplyAsync(() -> result * 2));
這樣,當 future1 完成時,它的結果會被傳遞給 future2 進行進一步處理。
2、thenCombine()
通過 thenCombine() 方法可以将兩個 CompletableFuture 對象的結果進行合并處理:
CompletableFuture<Integer> future1 = CompletableFuture.supplyAsync(() -> 10);
CompletableFuture<Integer> future2 = CompletableFuture.supplyAsync(() -> 20);
CompletableFuture<Integer> combinedFuture = future1.thenCombine(future2, (result1, result2) -> result1 + result2);
這裡的回調函數接受 future1 和 future2 的結果,并傳回它們的和。
3、allOf() 和 anyOf()
allOf() 方法接受一個 CompletableFuture 數組作為參數,等待所有的 CompletableFuture 都完成後傳回:
CompletableFuture<Integer> future1 = CompletableFuture.supplyAsync(() -> 10);
CompletableFuture<Integer> future2 = CompletableFuture.supplyAsync(() -> 20);
CompletableFuture<Void> allFutures = CompletableFuture.allOf(future1, future2);
anyOf() 方法接受一個 CompletableFuture 數組作為參數,等待任意一個 CompletableFuture 完成後傳回:
CompletableFuture<Integer> future1 = CompletableFuture.supplyAsync(() -> 10);
CompletableFuture<Integer> future2 = CompletableFuture.supplyAsync(() -> 20);
CompletableFuture<Object> anyFuture = CompletableFuture.anyOf(future1, future2);
三、異常處理和逾時
1、exceptionally()
通過 exceptionally() 方法可以處理任務執行過程中出現的異常,傳回一個預設值或者進行其他的異常處理邏輯。
2、handle()
handle() 方法類似于 exceptionally(),但是可以處理任務正常完成後的結果和異常情況。
3、whenComplete()
whenComplete() 方法接收一個 BiConsumer 參數,在任務完成後無論是否出現異常都會被調用,可以對任務的結果進行處理。
4、timeout()
可以使用 completeOnTimeout() 或者 orTimeout() 方法來設定任務的逾時時間。
四、并行流與 CompletableFuture
Java 8 還提供了并行流的功能,可以很友善地将一個集合的操作并行化。結合 CompletableFuture,我們可以更靈活地控制并行任務的執行順序和流程。
五、應用場景
CompletableFuture 可以應用于很多場景,包括:
- 并發執行多個任務,并等待所有任務完成後進行下一步操作;
- 異步擷取遠端資料,提高系統性能;
- 将多個阻塞 IO 操作組合成一個異步任務;
- 異步調用外部服務或接口。
總結一下,CompletableFuture 提供了一種簡潔而強大的方式來處理異步程式設計。通過組合多個 CompletableFuture 對象,可以實作複雜的任務流程和并發邏輯。它不僅提供了豐富的方法用于處理結果、處理異常和設定逾時,還能與并行流相結合,進一步提高程式的性能。