首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 相關知識

Java 8 CompletableFuture 異步編程全解析

     編輯:Java 相關知識

為什麼需要 CompletableFuture?

Future 接口僅支援阻塞獲取結果(get()),無法組合、鏈式處理異步任務。CompletableFuture 實現 CompletionStage,提供豐富的非阻塞組合式 API,支援回調、異常處理、多任務編排,是 Java 8 異步編程的基石。

核心 API 分類速覽

類別代表方法用途
結果轉換thenApply、thenCompose同步/異步映射、扁平化
消費結果thenAccept、thenRun無返回值的副作用操作
異常處理exceptionally、handle恢復或記錄異常
雙任務組合thenCombine、thenAcceptBoth、runAfterBoth雙結果合併、雙消費、雙運行
競態選擇applyToEither、acceptEither、runAfterEither取最快完成任務的結果
多任務編排allOf、anyOf等待全部/任一完成

關鍵場景代碼示例

1. 鏈式轉換(thenApply / thenCompose)

// thenApply: 同步映射 String -> Integer -> Double
CompletableFuture<Double> f3 = f1
    .thenApply(Integer::parseInt)
    .thenApply(r -> r * r * Math.PI);

// thenCompose: 函數返回 CompletableFuture,扁平化避免嵌套
CompletableFuture<Document> docFuture = loadDoc();
CompletableFuture<Double> relevance = docFuture
    .thenCompose(this::calculateRelevance); // calculateRelevance 返回 CF<Double>

2. 異常處理:exceptionally vs handle

// 僅處理異常,返回默認值
CompletableFuture<String> safe = future.exceptionally(ex -> "Default: " + ex.getMessage());

// 統一處理正常結果與異常(推薦)
CompletableFuture<Integer> safe2 = future.handle((ok, ex) -> {
    if (ok != null) return Integer.parseInt(ok);
    log.warn("Error", ex);
    return -1;
});

3. 兩個獨立異步任務合併(thenCombine)

CompletableFuture<Customer> custF = loadCustomer(123);
CompletableFuture<Shop> shopF = findNearestShop();

CompletableFuture<Route> routeF = custF.thenCombine(shopF, 
    (cust, shop) -> calculateRoute(cust, shop));
// routeF 在兩者完成後自動執行 calculateRoute

4. 等待多任務全部完成

CompletableFuture<Void> all = CompletableFuture.allOf(f1, f2, f3);
all.thenRun(() -> System.out.println("全部完成"));
// 或收集結果
List<String> results = Stream.of(f1, f2, f3)
    .map(CompletableFuture::join)
    .collect(Collectors.toList());

5. 競態:取最快響應

CompletableFuture<String> fast = fetchFromFastService();
CompletableFuture<String> stable = fetchFromStableService();

CompletableFuture<String> first = fast.applyToEither(stable, Function.identity());
// first 完成即表示兩者中最快者已返回

最佳實踐建議

  • 自定義執行器:耗時任務顯式傳入 Executor(如 thenApplyAsync(fn, executor)),避免佔用公共 ForkJoinPool。
  • 避免阻塞:盡量用 thenCompose/thenCombine 構建管道,少用 get()/join()。
  • 異常鏈路完整:關鍵節點加 handle 或 exceptionally,防止異常吞沒導致後續任務不執行。
  • 超時控制:JDK 9+ 可用 orTimeout/completeOnTimeout;JDK 8 需配合 ScheduledExecutorService 實現。

總結

CompletableFuture 將異步編程從「回調地獄」解脫,以聲明式組合替代命令式協調。掌握 轉換、組合、異常、編排 四大核心模式,即可構建高併發、高可維護的異步系統。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved