java - 为什么 completablefuture 不记录异常?

标签 java spring-boot completable-future

在 Spring Boot 应用程序中使用 CompletableFuture 时,我注意到使用 CompletableFuture 异步运行的函数中出现异常,但没有任何日志。函数执行停止,因此 CompletableFuture 完成。为什么日志里什么都没有? 当我将 .whenComplete 与 .runAsync 一起使用时,我能够记录错误。

void function() {
   CompletableFuture
     .runAsync(() -> runAsyncfunction())
     .whenComplete((result, err) -> {//log the error})
 }

编辑:如果我不使用.whenComplete JVM 不会打印 runAsyncfunction 中发生的未捕获异常的堆栈跟踪自动地。但如果我使用 .whenComplete我可以记录异常。

此外,使用 .whenComplete 是否是良好的行业实践?在这种情况下?

最佳答案

“JVM”不会自行打印异常堆栈跟踪。您需要编写代码来实现它。我能想到的唯一可能发生的情况是异常从 main() 中逃逸。否则,您编写的代码或您调用的代码具有打印堆栈跟踪的明确指令。也许如果您的代码是从某些 Spring Boot 代码调用的,Spring Boot 代码有一个异常处理程序可以为您执行此操作 - 我不知道,我不使用它。

在这种情况下

someFuture.runAsync(() -> runAsyncfunction());

当您调用 someFuture.runAsync() 时,您将返回一个新的 CompletableFuture,但您已忽略它。

当 someFuture 完成时,您的 runAsyncFunction() 将执行,可能在其他线程中。如果抛出异常,“您忽略的 future ”将异常完成。但你永远不会发现它,因为你忽略了会告诉你的机制。

总结一下:在其他线程(运行异步例程的线程)中引发了一些异常。那个异常在那里被捕获,并用来“异常地完成 future ”。但你需要做点什么才能发现 future 已经完成;在您这样做之前,它只是 future 未经检查的状态信息。

这个结构:

someFuture.runAsync(() -> runAsyncfunction())
          .whenComplete(blah blah);

相当于

CompletableFuture<Void> x =
    someFuture.runAsync(() -> runAsyncfunction());
x.whenComplete(blah blah);

也许这能让我们更清楚地了解这种情况下发生的事情。 “runAsync”失败,“x”异常完成。然后,whenComplete 会触发,您可以针对失败执行一些有用的操作。


脚注:发布的代码对我来说看起来无效。

CompletableFuture
   .runAsync(() -> runAsyncfunction())
   .whenComplete((result, err) -> {//log the error})

所以我希望我正确地猜出了你的意图。

关于java - 为什么 completablefuture 不记录异常?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/69839401/

相关文章:

Java - 本地类和泛型,为什么编译器警告?

java - 使用 Spring 进行海量多文件上传

java - 如果服务无法实现,应该返回什么

Spring 5 WebFlux Mono 和 Flux

java - CompletableFuture.runAsync(() ->... 带有非最终变量

java - 如何找到异常完成的 CompletableFuture

java - 是否可以在 switch 语句中使用类?

java - 如何在 JavaFX 中组合 FXML 文件和组?

java - JSP获取属性定义

java - 尽管 lambda 的返回类型,但 `thenApply()` 与 `thenCompose()` 不明确的情况是什么?