Luk*_*kas 7 java future java-8
我遇到过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));
}
Run Code Online (Sandbox Code Playgroud)
输出是:
After: java.util.concurrent.CompletionException: java.lang.RuntimeException
Before: java.lang.RuntimeException
Run Code Online (Sandbox Code Playgroud)
问题是,为什么异常包含CompletionException在一个案例中但不包含在另一个案例中?
更新:这是相关的错误报告.它已被标记并解析为JDK中的错误.
看起来像是jdk库中的一个错误。
在“After”情况下,向目标 future.thenCompose添加一个完成节点,其执行稍后由 触发。完成节点的方法在未来查找异常,并调用目标,将所有异常包装到. 请参阅此处如何创建节点,以及此处查看发生包装的位置。ThenCopy.completeExceptionallyrun.internalCompleteCompletionException
现在,在这种Before情况下,代码路径完全不同。因为 future 已经完成,.thenCompose所以不会创建额外的节点,而是立即调用回调,并简单地返回一个(已经完成的第二个 future),然后您可以在其上调用.whenComplete,这同样不会创建新的完成节点,但只是立即调用回调,为其提供第二个 future 的原始异常。
天哪,看看这段代码,我想向我的学生展示很多他们不应该做的事情......
| 归档时间: |
|
| 查看次数: |
3414 次 |
| 最近记录: |