我正在對我的資料庫進行多次異步呼叫。我將所有這些異步呼叫存盤在List<CompletableFuture<X>> list. 我想將所有結果收集在一起,所以我需要等待所有這些呼叫完成。
一種方法是創建一個 CompletableFuture.allOf(list.toArray(...))...
另一種方法是使用: list.stream.map(cf -> cf.join())...
我只是想知道創建全域 CompletableFuture 并等待它完成(當所有單個 CompletableFuture 完成時)與直接等待單個 CompletableFuture 完成相比是否有任何優勢。
uj5u.com熱心網友回復:
main無論哪種方式,執行緒都會被阻塞。
static CompletableFuture<Void> getFailingCF() {
return CompletableFuture.runAsync(() -> {
System.out.println("getFailingCF :: Started getFailingCF.. ");
throw new RuntimeException("getFailingCF:: Failed");
});
}
static CompletableFuture<Void> getOkCF() {
return CompletableFuture.runAsync(() -> {
System.out.println("getOkCF :: Started getOkCF.. ");
LockSupport.parkNanos(TimeUnit.SECONDS.toNanos(3));
System.out.println("getOkCF :: Completed getOkCF.. ");
});
}
public static void main(String[] args) {
List<CompletableFuture<Void>> futures = new ArrayList<>();
futures.add(getFailingCF());
futures.add(getOkCF());
// using CompletableFuture.allOf
var allOfCF = CompletableFuture.allOf(futures.toArray(new CompletableFuture[0]));
allOfCF.join();
// invoking join on individual CF
futures.stream()
.map(CompletableFuture::join)
.collect(Collectors.toList());
}
在上面的代碼片段中,區別在于處理例外:CompletableFuture.allOf(..)包裝任何CompletableFutures拋出的任何例外,同時允許其余執行緒(執行CompletableFuture)繼續執行。
該list.stream.map(cf -> cf.join())...方式立即拋出例外并終止應用程式(以及執行串列中 CF 的所有執行緒)。
請注意,呼叫join()onallOf也會引發包裝的例外。它也會終止應用程式。但是,此時,與 不同的是list.stream.map(cf -> cf.join())...,其余執行緒已經完成了它們的處理。
allOfCF.whenComplete(..) 是處理所有 CF 的執行結果(正常或例外)的優雅方式之一:
allOfCF.whenComplete((v, ex) -> {
System.out.println("In whenComplete...");
System.out.println("----------- Exception Status ------------");
System.out.println(" 1: " futures.get(0).isCompletedExceptionally());
System.out.println(" 2: " futures.get(1).isCompletedExceptionally());
});
在list.stream.map(cf -> cf.join())...方式,需要包裹join()呼叫try/catch。
轉載請註明出處,本文鏈接:https://www.uj5u.com/caozuo/344609.html
上一篇:當我從不使用Invoke或BeginInvoke時,無法呼叫Invoke或BeginInvoke錯誤
下一篇:為什么我們需要等待?
