gpt4 book ai didi

java - 为什么 Java 8 CompletableFuture thenCompose 根据完成顺序生成不同的异常?

转载 作者:塔克拉玛干 更新时间:2023-11-03 04:34:08 25 4
gpt4 key购买 nike

我遇到了 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中,而在另一种情况下却没有?

更新:Here是相关的错误报告。它已被标记为 JDK 中的错误并已解决。

最佳答案

似乎是 jdk 库中的错误。

在“After”情况下,.thenCompose 向目标 future 添加一个 ThenCopy 完成节点,其执行稍后由 .completeExceptionally 触发>。完成节点的 run 方法在 future 上发现异常,并在目标上调用 .internalComplete,将所有异常包装到 CompletionException 中。参见 here如何创建节点,以及 here包装发生的地方。

现在,在Before 的情况下,代码路径完全不同。因为 future 已经完成,.thenCompose 不会创建额外的节点,而是 invokes立即回调,并简单地返回一个(已经完成的第二个 future ),然后您在其上调用 .whenComplete,这同样不会费心创建一个新的完成节点,而只是简单地 invokes the callback马上,给它第二个 future 的原始异常(exception)。

child ,看看这段代码,我想向我的学生展示他们永远不应该做的事情的例子太多了......

关于java - 为什么 Java 8 CompletableFuture thenCompose 根据完成顺序生成不同的异常?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27747976/

25 4 0