在Spring中,CompletableFuture通常用於非同步編程,可以方便地處理非同步任務的執行和結果處理,CompletableFuture 是 Java 8 引入的一個類,用於支持非同步編程和併發操作。它基於 Future 和 CompletionStage 介面,提供了豐富的方法來處理非同步任務 ...
在Spring中,CompletableFuture通常用於非同步編程,可以方便地處理非同步任務的執行和結果處理,CompletableFuture
是 Java 8 引入的一個類,用於支持非同步編程和併發操作。它基於 Future 和 CompletionStage 介面,提供了豐富的方法來處理非同步任務的執行和結果處理。
下麵是 CompletableFuture
實現的一些關鍵原理:
-
線程池支持:
CompletableFuture
內部使用線程池來執行非同步任務,可以通過指定不同的線程池來控制任務的執行方式。預設情況下,CompletableFuture
使用ForkJoinPool.commonPool()
作為預設的線程池。 -
回調函數:
CompletableFuture
支持鏈式調用,可以通過thenApply()
,thenAccept()
,thenRun()
,thenCompose()
等方法添加回調函數,在非同步任務完成後處理任務的結果或執行下一步操作。 -
異常處理:
CompletableFuture
提供了exceptionally()
,handle()
,whenComplete()
等方法來處理非同步任務中可能拋出的異常,確保異常能夠被捕獲並處理。 -
組合操作:
CompletableFuture
支持多個 CompletableFuture 對象之間的組合操作,如thenCombine()
,thenCompose()
,allOf()
,anyOf()
等方法,實現並行執行、串列執行、等待所有任務完成等功能。 -
CompletableFuture 工廠方法:除了
supplyAsync()
方法外,CompletableFuture
還提供了一系列工廠方法來創建 CompletableFuture 對象,如runAsync()
,completedFuture()
,failedFuture()
等,方便快速創建並管理非同步任務。
總的來說,CompletableFuture
的實現基於 Future 和 CompletionStage 介面,利用線程池、回調函數、異常處理、組合操作等機制,提供了強大而靈活的非同步編程功能,使得開發人員能夠更加方便地處理非同步任務的執行和結果處理。
使用方法(一)鏈式
如果我們的業務方法已經寫完了,這時可以直接通過supplyAsync方法來調用這些已知的方法,而不需要重新開發
CompletableFuture<String> a1 = CompletableFuture.supplyAsync(() -> {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
return "Hello World";
});
CompletableFuture<String> a2 = CompletableFuture.supplyAsync(() -> {
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
return "Hello World";
});
CompletableFuture<String> a3 = CompletableFuture.supplyAsync(() -> {
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
return "Hello World";
});
// 這塊最後是並行計算時間為3秒
CompletableFuture.allOf(a1, a2, a3).join();
String result = a1.get() + " | " + a2.get() + " | " + a3.get();
使用方法(二)獨立方法
如果方法比較獨立,並且之前沒有開發過,那麼你可以通過非同步方法來將這些邏輯與調用代碼解耦
@Service
@EnableAsync
public class ParallelTaskService {
@Async
public CompletableFuture<String> task1() {
// 模擬一個耗時操作
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
return CompletableFuture.completedFuture("Task 1 completed");
}
@Async
public CompletableFuture<String> task2() {
// 模擬另一個耗時操作
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
return CompletableFuture.completedFuture("Task 2 completed");
}
}
// 並行計算時,響應時間是2和3秒之中最大值,即3秒
@GetMapping("/hello-world2")
public CompletableFuture<String> helloWorld2() {
CompletableFuture<String> task1Result = parallelTaskService.task1();
CompletableFuture<String> task2Result = parallelTaskService.task2();
// 等待所有任務都完成
CompletableFuture<Void> allOf = CompletableFuture.allOf(task1Result, task2Result);
// 處理所有任務完成後的邏輯
return allOf.thenApply(voidResult -> {
String result = task1Result.join() + " | " + task2Result.join();
return result;
});
}
作者:倉儲大叔,張占嶺,
榮譽:微軟MVP
QQ:853066980
支付寶掃一掃,為大叔打賞!