![](/img/trans.png)
[英]Only execute CompletableFuture callback when status of result is completed
[英]CompletableFuture callback not called if completed manually
在CompletableFuture的這個基本示例中,我異步運行了一個任務,當它完成時,應該觸發一個異步回調。
在我開始運行任務后一秒鍾,在它完成之前,我完成了它。 之后,我不再看到它運行異步回調。
public static void main(String[] args) throws InterruptedException {
runTask();
Thread.sleep(1000);
completableFuture.complete("Test");
Thread.sleep(4000);
}
public static void runTask() {
completableFuture = CompletableFuture.supplyAsync(() -> {
System.out.println("Running...");
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("...finished");
return "finished task";
})
.thenApplyAsync(s -> {
System.out.println("Apply on result: " + s);
return "Result: " + s;
})
}
結果是:
Running...
...finished
問題是,如果我添加另一個回調,那么它會運行第一個而不是第二個。
.thenApplyAsync(s -> {
System.out.println("Second apply with result: " + s);
return "Result: " + s;
})
那么結果是:
Running...
...finished
Apply on result: finished task
閱讀文檔后,我了解到所有回調都會被調用,即使未來是手動完成的。 我在這里錯過了什么嗎?
我想如果你寫得稍微不同,它應該是有道理的:
public static void runTask() {
CompletableFuture<String> one = CompletableFuture.supplyAsync(() -> {
System.out.println("Running...");
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("...finished");
return "finished task";
});
CompletableFuture<String> two = one.thenApplyAsync(s -> {
System.out.println("Apply on result: " + s);
return "Result: " + s;
});
completableFuture = two;
}
所以,在你的情況下, one
開始就好了,但是在two
甚至可以開始之前,你發出completableFuture.complete("Test");
. 因此,當one
完成時, thenApplyAsync
沒有任何內容,因為那個已經完成了。
當您再添加一個階段時,您基本上會得到:
....
CompletableFuture<String> two = one.thenApplyAsync(s -> {
System.out.println("Apply on result: " + s);
return "Result: " + s;
});
CompletableFuture<String> three = two.thenApplyAsync(s -> {
System.out.println("Second apply with result: " + s);
return "Result: " + s;
});
completableFuture = three;
你可能會看到這里發生了什么,甚至不用我解釋。
為此,我看不出文檔在哪里可以清楚地說明這一點。 我想我們需要通過以下方式在package 文檔中看到這一點:
當兩個或更多線程嘗試完成、完成異常或取消 CompletableFuture 時,只有其中一個成功。
這在某種程度上意味着,如果某個階段尚未開始,但由其他人完成,則在外部complete
它; 那個階段根本不會運行。 這是有道理的,但 package 文檔可能更清楚,imo。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.