30+個 CompletableFuture 高頻場景案例,讓你的系統性能飆升300%
環境:SpringBoot3.4.2
1. 簡介
什么是CompletableFuture?
CompletableFuture 位于 JUC 包中,用于表示異步計算的未來結果。與傳統的Future不同(傳統Future僅允許在計算完成后獲取結果),CompletableFuture提供了豐富的API來構建復雜的異步操作流水線。它支持多種操作,例如合并多個Future、處理異常以及非阻塞地執行任務等。
CompletableFuture的核心特性:
- 非阻塞:可以在不阻塞主線程的情況下執行任務
- 任務鏈式調用:可以將多個異步任務串聯在一起
- 異常處理:提供了更優雅的異常處理方法
- 合并Future:可以將多個Future合并為一個Future
何時使用:
- 異步操作:當需要執行可以獨立運行而無需相互等待的任務時
- I/O操作:非常適合網絡調用、文件I/O或數據庫查詢等存在延遲的場景
- 復雜工作流:當有多個相互依賴或獨立的任務需要按特定順序執行時
為什么使用:
- 提升性能:通過利用非阻塞操作,可以更好地利用系統資源,提高應用程序的響應能力
- 簡化代碼:與傳統的回調方式相比,它有助于更優雅地管理異步代碼
- 優雅的異常處理:提供了內置的機制來處理異步處理過程中可能出現的異常
接下來,我們將詳細介紹使用CompletableFuture的50個常見使用場景。
2.實戰案例
2.1 簡單異步任務
CompletableFuture.runAsync(() -> {
System.out.println("異步線程執行任務");
});2.2 異步任務返回結果
CompletableFuture<Integer> future = CompletableFuture.supplyAsync(() -> 42) ;2.3 使用 thenApply 鏈式任務
CompletableFuture<Integer> future = CompletableFuture
.supplyAsync(() -> 10)
.thenApply(result -> result * 2);2.4 使用thenAccept處理結果
CompletableFuture.supplyAsync(() -> 10)
.thenAccept2.5 任務完成而不消費結果(thenRun)
CompletableFuture.supplyAsync(() -> 10)
.thenRun(() -> System.out.println("任務執行完成.")) ;2.6 使用 thenCombine 組合兩個Future
CompletableFuture<Integer> f1 = CompletableFuture.supplyAsync(() -> 10);
CompletableFuture<Integer> f2 = CompletableFuture.supplyAsync(() -> 20);
CompletableFuture<Integer> ret = f1.thenCombine(f2, Integer::sum);
ret.thenAccept(result -> System.out.println("合并后的結果: " + result));2.7 用 allOf 等待所有Future
CompletableFuture<Void> allFutures = CompletableFuture.allOf(
CompletableFuture.supplyAsync(() -> "Task 1"),
CompletableFuture.supplyAsync(() -> "Task 2")
);
// 主線程將被阻塞
allFutures.join();2.8 使用 anyOf 等待任何一個完成
CompletableFuture<Object> anyFuture = CompletableFuture.anyOf(
CompletableFuture.supplyAsync(() -> {
try {TimeUnit.SECONDS.sleep(3) ;} catch (InterruptedException e) {}
return "Task 1" ;
}),
CompletableFuture.supplyAsync(() -> {
try {TimeUnit.SECONDS.sleep(1) ;} catch (InterruptedException e) {}
return "Task 2" ;
})
);
anyFuture.thenAccept(result -> System.out.println("第一個完成的: " + result)) ;上面代碼輸出:Task 2。
2.9 使用exceptionally處理異常
CompletableFuture<Integer> future = CompletableFuture.supplyAsync(() -> {
System.err.println(1 / 0) ;
return 666 ;
}).exceptionally(ex -> {
System.out.println("Exception: " + ex.getMessage());
return -1 ;
});
System.err.println(future.get()) ;輸出:-1。
2.10 使用 handle 同時處理結果和異常
CompletableFuture<Integer> future = CompletableFuture.supplyAsync(() -> {
System.err.println(1 / 0) ;
return 666 ;
}).handle((result, ex) -> {
if (ex != null) {
return 0;
}
return result;
});當supplyAsync方法執行時拋出異常則通過handle捕獲并返回默認值0,否則返回結果666。
2.11 在另一個任務完成后運行任務(thenCompose)
CompletableFuture<Integer> future = CompletableFuture.supplyAsync(() -> 10)
.thenCompose(result -> CompletableFuture.supplyAsync(() -> result * 2)) ;該代碼通過thenCompose鏈式組合兩個異步任務,將前一個結果(10)乘以2,最終得到CompletableFuture<Integer>(值為20)。
2.12 異步HTTP請求
HttpClient client = HttpClient.newHttpClient();
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create("http://localhost:8080/users/1"))
.build();
CompletableFuture<HttpResponse<String>> future = client.sendAsync(request, HttpResponse.BodyHandlers.ofString());
future.thenAccept(respons使用HttpClient異步發送HTTP請求,通過CompletableFuture處理響應字符串,非阻塞獲取結果。
輸出結果
{"id":1,"name":"姓名 - 1","age":72}2.13 指定運行任務的線程池
ThreadPoolExecutor executor = new ThreadPoolExecutor(2, 2, 60, TimeUnit.SECONDS, new ArrayBlockingQueue<>(2)) ;
CompletableFuture.runAsync(() -> {
System.out.printf("%s - 執行任務") ;
}, executor);2.14 鏈式執行多個Future
CompletableFuture<Integer> future = CompletableFuture.supplyAsync(() -> 10)
.thenApply(result -> result + 5)
.thenApply(result -> result * 2);
future.thenAccept(result -> System.out.println("最終結果: " + result)) ;前一個任務執行的結果作為下一個任務的入參。
2.15 手動完成Future
CompletableFuture<Integer> future = new CompletableFuture<>();
future.complete(10);
future.thenAccept(result -> System.out.println("最終結果: " + result));
future.join() ;2.16 設定任務執行超時時間
CompletableFuture<Integer> future = CompletableFuture.supplyAsync(() -> {
try { Thread.sleep(2000); } catch (InterruptedException e) { }
return 10;
});
future.orTimeout(1, TimeUnit.SECONDS).exceptionally(ex -> {
System.out.println("任務執行超時...");
return null ;
});
future.join() ;運行結果

2.17 超時任務返回默認值
CompletableFuture.supplyAsync(() -> {
try { Thread.sleep(2000); } catch (InterruptedException e) { }
return 10;
})
.completeOnTimeout(666, 1, TimeUnit.SECONDS)
.thenAccept(result -> System.out.println("Result: " + result));運行結果
Result:6662.18 使用Stream API組合多個Future
List<CompletableFuture<Integer>> futures = List.of(
CompletableFuture.supplyAsync(() -> 10),
CompletableFuture.supplyAsync(() -> 20),
CompletableFuture.supplyAsync(() -> 30)
);
CompletableFuture<Void> combinedFuture = CompletableFuture.allOf(
futures.toArray(new CompletableFuture[0])
);
combinedFuture.thenAccept(result -> {
List<Integer> results = futures.stream()
.map(CompletableFuture::join)
.toList() ;
System.out.println(results) ;
}).join();運行結果
[10, 20, 30]2.19 指定延遲完成任務
CompletableFuture<Integer> future = new CompletableFuture<>();
Executors.newSingleThreadScheduledExecutor().schedule(() -> {
future.complete(42) ;
}, 2, TimeUnit.SECONDS) ;
future.thenAccept(System.out::println).join() ;延遲2s后輸出結果42。
2.20 使用 thenAcceptBoth 組合兩個結果
CompletableFuture<Integer> future1 = CompletableFuture.supplyAsync(() -> 10);
CompletableFuture<Integer> future2 = CompletableFuture.supplyAsync(() -> 20);
future1.thenAcceptBoth(future2, (res1, res2) -> {
System.out.println("合并結果: " + (res1 + res2));
}).join() ;2.21 acceptEither優先處理先完成的異步任務結果
CompletableFuture<Integer> future1 = CompletableFuture.supplyAsync(() -> {
try {TimeUnit.SECONDS.sleep(3) ;} catch (InterruptedException e) {e.printStackTrace();}
return 10 ;
});
CompletableFuture<Integer> future2 = CompletableFuture.supplyAsync(() -> {
try {TimeUnit.SECONDS.sleep(2) ;} catch (InterruptedException e) {e.printStackTrace();}
return 20 ;
});
future1.acceptEither(future2, result -> {
System.out.println("結果: " + result);
}).join() ;輸出結果:20。
acceptEither 取 future1 和 future2 中先完成的結果,非阻塞處理(輸出先到達的值,10 或 20)。
2.22 取消任務執行
CompletableFuture<Integer> future = CompletableFuture.supplyAsync(() -> {
try { Thread.sleep(2000); } catch (InterruptedException e) { }
return 10;
});
future.cancel(true) ;2.23 使用 whenComplete 完成最終任務
CompletableFuture.supplyAsync(() -> 10)
.whenComplete((result, ex) -> {
System.out.println("Final result: " + result);
}).join();2.24 處理流式Future
List<CompletableFuture<Integer>> futures = List.of(
CompletableFuture.supplyAsync(() -> {
try { Thread.sleep(2000); } catch (InterruptedException e) { }
return 1 ;
}),
CompletableFuture.supplyAsync(() -> {
try { Thread.sleep(1000); } catch (InterruptedException e) { }
return 2 ;
}),
CompletableFuture.supplyAsync(() -> {
try { Thread.sleep(3000); } catch (InterruptedException e) { }
return 3 ;
})
);
futures.forEach(future -> future.thenAccept(result -> System.out.println("Result: " + result))) ;輸出結果:
Result: 2
Result: 1
Result: 32.25 使用 completeExceptionally 進行異常處理
CompletableFuture<Integer> future = new CompletableFuture<>();
future.completeExceptionally(new RuntimeException("任務執行錯誤"));
future.exceptionally(ex -> {
System.out.println("Exception: " + ex.getMessage());
return 0;
});2.26 使用 thenComposeAsync 進行順序處理
CompletableFuture<Integer> future = CompletableFuture.supplyAsync(() -> 5)
.thenComposeAsync(result -> CompletableFuture.supplyAsync(() -> result * 2));
future.thenAccept(result ->thenComposeAsync:異步轉換結果并鏈式執行后續任務,非阻塞串聯異步邏輯。
2.27 使用 thenCombineAsync 組合任務
CompletableFuture<Integer> future1 = CompletableFuture.supplyAsync(() -> 10);
CompletableFuture<Integer> future2 = CompletableFuture.supplyAsync(() -> 20);
CompletableFuture<Integer> combinedFuture = future1.thenCombineAsync(future2, Integer::sum);
combinedFuture.thenAccept(r2.28 阻塞式等待直至完成
CompletableFuture<Integer> future = CompletableFuture.supplyAsync(() -> 42);
Integer result = future.get(); // 阻塞直到任務執行完成
System.out.println("結果: " + result);2.29 合并不同類型的Future
CompletableFuture<Integer> future1 = CompletableFuture.supplyAsync(() -> 10);
CompletableFuture<String> future2 = CompletableFuture.supplyAsync(() -> "Result");
CompletableFuture<String> combinedFuture = future1.thenCombine(future2, (num, str) -> num + " " + str);
combinedFuture.then2.30 使用 thenCombine 和 thenCompose 組合結果
CompletableFuture<Integer> future1 = CompletableFuture.supplyAsync(() -> 10);
CompletableFuture<Integer> future2 = CompletableFuture.supplyAsync(() -> 20);
CompletableFuture<Integer> finalFuture = future1.thenCombine(future2, Integer::sum)
.thenCompose(result -> CompletableFuture.supplyAsync(() -> result * 2));
finalFuture.thenAccept(r2.31 使用 handleAsync 處理異常
CompletableFuture<Integer> future = CompletableFuture.supplyAsync(() -> {
System.err.println(1 / 0) ;
return 888 ;
}).handleAsync((result, ex) -> {
if (ex != null) {
System.out.println("Handled exception");
return 0;
}
return result;
});2.32 等待多個Future(帶超時)
List<CompletableFuture<Integer>> futures = List.of(
CompletableFuture.supplyAsync(() -> 10),
CompletableFuture.supplyAsync(() -> 20)
);
CompletableFuture<Void> combinedFuture = CompletableFuture.allOf(futures.toArray(new CompletableFuture[0]))
.orTimeout(1, TimeUnit.SECONDS);
combinedFuture.thenRun(() -> System.o





























