首页 > 解决方案 > 为什么这段代码的结果是不确定的?

问题描述

我希望下面的代码总是打印“错误”,但有时它会打印“外部”。我想要发生的是让“外部”完成,让“内部”使用“外部”的结果来生成自己的结果,如果未来失败,则失败。我究竟做错了什么?

        CompletableFuture<String> outer = CompletableFuture.supplyAsync(() -> "outer");
        CompletableFuture<String> inner = CompletableFuture.supplyAsync(() -> "inner");
        inner.completeExceptionally(new IllegalArgumentException());
        CompletableFuture<String> both = outer.thenApply(s -> {
            try {
                String i = inner.get();
                return s + i;
            } catch (InterruptedException |ExecutionException e) {
                throw new IllegalStateException(e);
            }
        });

        try {
            String o = both.get();
            System.out.println(o);
        } catch (ExecutionException | InterruptedException e) {
            System.err.println("Errored");
        }

标签: javamultithreadingcompletable-future

解决方案


理解这一点实际上是微不足道的。您需要更仔细地查看:

CompletableFuture<String> inner = CompletableFuture.supplyAsync(() -> "inner");

特别是您所说的事实supplyAsync,这意味着在不同的线程中。在您的主线程(或任何其他线程)中,您执行以下操作:inner.completeExceptionally(new IllegalArgumentException());

哪个线程应该获胜?supplyAsync你跑的那个人还是那个人inner.completeExceptionally?当然,文档中completeExceptionally提到了这一点......这是一个基本的“竞赛”,哪个线程首先达到“完成”(通常或通过异常)inner


推荐阅读