30+個 CompletableFuture 高頻場景案例,讓你的系統(tǒng)性能飆升300%
環(huán)境:SpringBoot3.4.2
1. 簡介
什么是CompletableFuture?
CompletableFuture 位于 JUC 包中,用于表示異步計算的未來結(jié)果。與傳統(tǒng)的Future不同(傳統(tǒng)Future僅允許在計算完成后獲取結(jié)果),CompletableFuture提供了豐富的API來構(gòu)建復(fù)雜的異步操作流水線。它支持多種操作,例如合并多個Future、處理異常以及非阻塞地執(zhí)行任務(wù)等。
CompletableFuture的核心特性:
- 非阻塞:可以在不阻塞主線程的情況下執(zhí)行任務(wù)
 - 任務(wù)鏈?zhǔn)秸{(diào)用:可以將多個異步任務(wù)串聯(lián)在一起
 - 異常處理:提供了更優(yōu)雅的異常處理方法
 - 合并Future:可以將多個Future合并為一個Future
 
何時使用:
- 異步操作:當(dāng)需要執(zhí)行可以獨立運行而無需相互等待的任務(wù)時
 - I/O操作:非常適合網(wǎng)絡(luò)調(diào)用、文件I/O或數(shù)據(jù)庫查詢等存在延遲的場景
 - 復(fù)雜工作流:當(dāng)有多個相互依賴或獨立的任務(wù)需要按特定順序執(zhí)行時
 
為什么使用:
- 提升性能:通過利用非阻塞操作,可以更好地利用系統(tǒng)資源,提高應(yīng)用程序的響應(yīng)能力
 - 簡化代碼:與傳統(tǒng)的回調(diào)方式相比,它有助于更優(yōu)雅地管理異步代碼
 - 優(yōu)雅的異常處理:提供了內(nèi)置的機制來處理異步處理過程中可能出現(xiàn)的異常
 
接下來,我們將詳細(xì)介紹使用CompletableFuture的50個常見使用場景。
2.實戰(zhàn)案例
2.1 簡單異步任務(wù)
CompletableFuture.runAsync(() -> {
  System.out.println("異步線程執(zhí)行任務(wù)");
});2.2 異步任務(wù)返回結(jié)果
CompletableFuture<Integer> future = CompletableFuture.supplyAsync(() -> 42) ;2.3 使用 thenApply 鏈?zhǔn)饺蝿?wù)
CompletableFuture<Integer> future = CompletableFuture
        .supplyAsync(() -> 10)
        .thenApply(result -> result * 2);2.4 使用thenAccept處理結(jié)果
CompletableFuture.supplyAsync(() -> 10)
  .thenAccept2.5 任務(wù)完成而不消費結(jié)果(thenRun)
CompletableFuture.supplyAsync(() -> 10)
      .thenRun(() -> System.out.println("任務(wù)執(zhí)行完成.")) ;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("合并后的結(jié)果: " + 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 同時處理結(jié)果和異常
CompletableFuture<Integer> future = CompletableFuture.supplyAsync(() -> {
  System.err.println(1 / 0) ;
  return 666 ;
}).handle((result, ex) -> {
  if (ex != null) {
    return 0;
  }
  return result;
});當(dāng)supplyAsync方法執(zhí)行時拋出異常則通過handle捕獲并返回默認(rèn)值0,否則返回結(jié)果666。
2.11 在另一個任務(wù)完成后運行任務(wù)(thenCompose)
CompletableFuture<Integer> future = CompletableFuture.supplyAsync(() -> 10)
    .thenCompose(result -> CompletableFuture.supplyAsync(() -> result * 2)) ;該代碼通過thenCompose鏈?zhǔn)浇M合兩個異步任務(wù),將前一個結(jié)果(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異步發(fā)送HTTP請求,通過CompletableFuture處理響應(yīng)字符串,非阻塞獲取結(jié)果。
輸出結(jié)果
{"id":1,"name":"姓名 - 1","age":72}2.13 指定運行任務(wù)的線程池
ThreadPoolExecutor executor = new ThreadPoolExecutor(2, 2, 60, TimeUnit.SECONDS, new ArrayBlockingQueue<>(2)) ;
CompletableFuture.runAsync(() -> {
  System.out.printf("%s - 執(zhí)行任務(wù)") ;
}, executor);2.14 鏈?zhǔn)綀?zhí)行多個Future
CompletableFuture<Integer> future = CompletableFuture.supplyAsync(() -> 10)
    .thenApply(result -> result + 5)
    .thenApply(result -> result * 2);
future.thenAccept(result -> System.out.println("最終結(jié)果: " + result)) ;前一個任務(wù)執(zhí)行的結(jié)果作為下一個任務(wù)的入?yún)ⅰ?/span>
2.15 手動完成Future
CompletableFuture<Integer> future = new CompletableFuture<>();
future.complete(10);
future.thenAccept(result -> System.out.println("最終結(jié)果: " + result));
future.join() ;2.16 設(shè)定任務(wù)執(zhí)行超時時間
CompletableFuture<Integer> future = CompletableFuture.supplyAsync(() -> {
  try { Thread.sleep(2000); } catch (InterruptedException e) { }
  return 10;
});
future.orTimeout(1, TimeUnit.SECONDS).exceptionally(ex -> {
  System.out.println("任務(wù)執(zhí)行超時...");
  return null ;
});
future.join() ;運行結(jié)果

2.17 超時任務(wù)返回默認(rèn)值
CompletableFuture.supplyAsync(() -> {
  try { Thread.sleep(2000); } catch (InterruptedException e) { }
  return 10;
})
.completeOnTimeout(666, 1, TimeUnit.SECONDS)
.thenAccept(result -> System.out.println("Result: " + result));運行結(jié)果
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();運行結(jié)果
[10, 20, 30]2.19 指定延遲完成任務(wù)
CompletableFuture<Integer> future = new CompletableFuture<>();
Executors.newSingleThreadScheduledExecutor().schedule(() -> {
  future.complete(42) ;
}, 2, TimeUnit.SECONDS) ;
future.thenAccept(System.out::println).join() ;延遲2s后輸出結(jié)果42。
2.20 使用 thenAcceptBoth 組合兩個結(jié)果
CompletableFuture<Integer> future1 = CompletableFuture.supplyAsync(() -> 10);
CompletableFuture<Integer> future2 = CompletableFuture.supplyAsync(() -> 20);
future1.thenAcceptBoth(future2, (res1, res2) -> {
    System.out.println("合并結(jié)果: " + (res1 + res2));
}).join() ;2.21 acceptEither優(yōu)先處理先完成的異步任務(wù)結(jié)果
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("結(jié)果: " + result);
}).join() ;輸出結(jié)果:20。
acceptEither 取 future1 和 future2 中先完成的結(jié)果,非阻塞處理(輸出先到達的值,10 或 20)。
2.22 取消任務(wù)執(zhí)行
CompletableFuture<Integer> future = CompletableFuture.supplyAsync(() -> {
  try { Thread.sleep(2000); } catch (InterruptedException e) { }
  return 10;
});
future.cancel(true) ;2.23 使用 whenComplete 完成最終任務(wù)
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))) ;輸出結(jié)果:
Result: 2
Result: 1
Result: 32.25 使用 completeExceptionally 進行異常處理
CompletableFuture<Integer> future = new CompletableFuture<>();
future.completeExceptionally(new RuntimeException("任務(wù)執(zhí)行錯誤"));
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:異步轉(zhuǎn)換結(jié)果并鏈?zhǔn)綀?zhí)行后續(xù)任務(wù),非阻塞串聯(lián)異步邏輯。
2.27 使用 thenCombineAsync 組合任務(wù)
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();  // 阻塞直到任務(wù)執(zhí)行完成
System.out.println("結(jié)果: " + 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 組合結(jié)果
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














 
 
 












 
 
 
 