gpt4 book ai didi

java - 在可完成的 future 之内/之后抛出异常

转载 作者:行者123 更新时间:2023-11-29 08:20:53 32 4
gpt4 key购买 nike

我有一个这样的可完成 future 列表:

List<CompletableFuture<MyObject>> futures = class_list.stream()
.map(c -> CompletableFuture.supplyAsync(() ->
try {
return helper(c);
} catch (Throwable th) {
throw th; // doesn't work
}
))
.exceptionally(ex -> {
throw ex; // also didn't work
}

然后我遍历我的 futures 并尝试再次抛出异常:

futures.stream.map(f -> {
try {
return f.get();
}catch(Completionexception ex){
throw new ex; (also didn't work)
}

理想情况下,我希望在发现可抛出的异常时退出整个异步过程。

最佳答案

不需要像

这样的结构
try { 
return helper(c);
}catch(Throwable th) {
throw th;
}

因为捕获并重新抛出异常的行为与首先不捕获异常没有什么不同。同样,如果合法,链接 .exceptionally(ex -> { throw ex; } 将毫无意义。(事实并非如此,因为 Throwable 是一个已检查的异常。

如果 helper 不抛出已检查的异常,您可以简单地使用 CompletableFuture.supplyAsync(() -> helper(c))。否则,您必须将已检查的异常包装到未检查的异常中;这里最自然的选择是 CompletionException

这看起来像:

List<CompletableFuture<MyObject>> futures = class_list.stream()
.map(c -> CompletableFuture.supplyAsync(() ->
try {
return helper(c);
} catch(Throwable th) {
throw new CompletionException(th);
}
))
.collect(Collectors.toList());

你的第二个操作很草率。类名是 CompletionException,而不是 Completionexception。此外,抛出存储在变量 ex 中的现有异常是通过 throw ex; 而不是 throw new ex; 完成的。但如前所述,当您希望(重新)抛出异常时,首先不要捕获它。

问题是 get 抛出已检查的 ExecutionException 而不是未检查的 CompletionException。对于后者,您必须使用 join。所以你可以通过

实现预期的重新抛出
 // will throw when any future completed exceptionally
futures.forEach(CompletableFuture::join);

关于java - 在可完成的 future 之内/之后抛出异常,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58662840/

32 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com