java - 为什么这段代码的结果是不确定的?
问题描述
我希望下面的代码总是打印“错误”,但有时它会打印“外部”。我想要发生的是让“外部”完成,让“内部”使用“外部”的结果来生成自己的结果,如果未来失败,则失败。我究竟做错了什么?
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");
}
解决方案
理解这一点实际上是微不足道的。您需要更仔细地查看:
CompletableFuture<String> inner = CompletableFuture.supplyAsync(() -> "inner");
特别是您所说的事实supplyAsync
,这意味着在不同的线程中。在您的主线程(或任何其他线程)中,您执行以下操作:inner.completeExceptionally(new IllegalArgumentException());
。
哪个线程应该获胜?supplyAsync
你跑的那个人还是那个人inner.completeExceptionally
?当然,文档中completeExceptionally
提到了这一点......这是一个基本的“竞赛”,哪个线程首先达到“完成”(通常或通过异常)inner
。
推荐阅读
- c# - 将 CString 数组从 MFC c++ dll 返回到 C# 程序
- python - 如何将 matlab 合并到 jupyter notebook 中?
- asp.net - 如何将 React 应用程序部署到 Azure 中的虚拟应用程序?
- java - 为什么要使用html数据属性
- arrays - 为什么这段代码要求我在函数声明中包含数组的大小?
- java - 在调试器中将 Java GET 请求转换为 GET 请求
- php - 如何检查 jquery post 返回的 json 对象中的键?
- json - 如何将 json 对象转换为 prestodb/athena 中的数组
- node.js - nodejs 的 Azure Redis 键空间通知问题
- eclipse - 如何从 github 导入特定项目