![](/img/trans.png)
[英]Java CompletableFuture thenCompose with several async tasks
[英]Why Java 8 CompletableFuture thenCompose generates different exception depending on the order of completion?
我遇到過Java 8 CompletableFuture thenCompose方法的奇怪行為。 我有兩個測試,僅在執行順序上有所不同。 兩個測試都模擬thenCompose中生成的CompletableFuture中的失敗。
@Test
public void completedAfter() {
CompletableFuture<String> future1 = new CompletableFuture<>();
CompletableFuture<String> future2 = new CompletableFuture<>();
future1.thenCompose(x -> future2).whenComplete((r, e) -> System.out.println("After: " + e));
future1.complete("value");
future2.completeExceptionally(new RuntimeException());
}
@Test
public void completedBefore() {
CompletableFuture<String> future1 = new CompletableFuture<>();
CompletableFuture<String> future2 = new CompletableFuture<>();
future1.complete("value");
future2.completeExceptionally(new RuntimeException());
future1.thenCompose(x -> future2).whenComplete((r, e) -> System.out.println("Before: " +e));
}
輸出是:
After: java.util.concurrent.CompletionException: java.lang.RuntimeException
Before: java.lang.RuntimeException
問題是,為什么在一個案例中包含在CompletionException
中但在另一個案例中卻沒有包含異常?
更新: 這是相關的錯誤報告。 它已被標記並解析為JDK中的錯誤。
好像是jdk庫中的一個bug。
在“After”情況下, .thenCompose
將一個ThenCopy
完成節點添加到目標future,其執行稍后由.completeExceptionally
觸發。 完成節點的run
方法在將來找到異常,並在目標上調用.internalComplete
,它將所有異常包裝到CompletionException
。 請參閱此處如何創建節點,以及此處的包裝發生位置。
現在,在Before
案例中,代碼路徑完全不同。 因為未來已經完成, .thenCompose
不會創建額外的節點,而是立即調用回調,然后只返回一個(已經完成的第二個未來),然后調用.whenComplete
,再次,它無需創建一個新的完成節點,但只是立即調用回調 ,從第二個未來給它原始的異常。
男孩,看着這段代碼,有很多例子我想向學生展示他們應該做的事情......
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.