CompletableFuture with Runnable-delegation - 在委托中忽略异常 class

CompletableFuture with Runnable-delegation - exception is ignored in delegating class

我在使用 CompletableFuture 将我的代码转换为非阻塞代码时遇到问题。为了尽量减少问题的范围,我创建了一个 sample code,它在我使用 CompletableFuture 时表现不同。问题是 CompletableFuture 吞下了来自 Runnable-delegation 的异常。

我在 Runnable 和 ExecutorService 之上使用委托来提供我的原始应用程序所需的一些包装器代码。

示例代码:

问题: 当我运行 way1()时,输出是

    Way:1 # This is main class : main
    Delegating Thread start : pool-1-thread-1
    This is My Thread throwing exception : pool-1-thread-1
    ###### Delegating Thread Exception Caught : pool-1-thread-1
    main class completed : main
    Delegating Thread ends : pool-1-thread-1

你可以注意到 'DelegatingRunnable' 的 catch 块可以捕获这里的异常,这是从 MyRunnable 引发的。但是,如果我使用 CompletableFuture 使用 way2(),MyRunnable 的异常不会在 DelegatingRunnable 下咳嗽,尽管我看到它在 CompletableFuture 的 'whenComplete' 回调下咳嗽。

way2的输出是

    Way:2 # This is main class : main
    Delegating Thread start : pool-1-thread-1
    This is My Thread throwing exception : pool-1-thread-1
    Delegating Thread ends : pool-1-thread-1
    whenComplete - exception  : main
    main class completed : main

您可以注意到 CompletableFuture 在内部使用相同的 DelegatingExecutionService 和 DelegatingRunnable。我不明白为什么 DelegatingRunnable 在这种情况下无法捕获异常。

(为什么我要使用 CompletableFuture?-这只是一个示例代码,用于解释我所面临的确切问题。但总的来说,我需要使用 CompletableFuture 以非阻塞方式最终创建任务链)

CompletableFuture 的源代码中,您可以看到它将给定的 Runnable 包装在一个 AsyncRun 类型的对象中,该对象本身实现了 Runnable。 此 AsyncRun 将传递给执行程序的 execute 方法。 当 inner/original Runnable 抛出异常时,它会被 AsyncRun 的代码捕获并且 CompletableFuture 完成为失败但异常将 not 被重新抛出。

这就是为什么您的包装器 (DelegatingRunnable) 永远不会看到异常的原因。