CompletableFuture.exceptionally() method takes a lambda, but there is no flavor of the method that takes a custom Executor, or even an "...Async" flavor of it.
Which executor does exceptionally lambda run on? Would it be the same executor which ran the original CompletableFuture which threw the exception? Or (I would be surprised if this is the case) is it the commonPool ?
CompletableFuture.exceptionally does not take an Executor argument since it is not designed to execute the exceptionally task asynchronously. If the dependent task is not yet completed then the exceptionally task will complete on the same thread that dependent tasks completes on.
In this case no exception is thrown by Java unless we call get () or join () methods. On calling these methods CompletionException is thrown which wraps the actual exception as the root cause exception. Also we can use CompletableFuture.isCompletedExceptionally () method to determine if a CompletableFuture completed with an exception.
What is CompletableFuture.completeExceptionally () in Java? completeExceptionally () is an instance method of the CompletableFuture which is used to complete the future with the given exception. The subsequent calls to methods where we can retrieve results like get () and join () throwing the given exception.
Methods completeAsync () The completeAsync method should be used to complete the CompletableFuture asynchronously using the value given by the Supplier provided. The difference between this two overloaded methods is the existence of the second argument, where the Executor running the task can be specified.
Form JDK bug discussion CompletableFuture.exceptionally may execute on main thread :
CompletableFuture.exceptionally
does not take an Executor argument since it is not designed to execute the exceptionally task asynchronously.If the dependent task is not yet completed then the exceptionally task will complete on the same thread that dependent tasks completes on.
If the dependent task is completed then the exceptionally task will complete on the thread that executed the call to exceptionally.
This is the same behaviour that will occur for any non-asynchronous execution, such as thenAccept.
To guarantee that the exceptionally task is executed on a thread within the executor thread pool then it is necessary to use whenCompleteAsync or handleAsync and passing in the executor.
Note that as of JDK 12, there is CompletionStage.exceptionallyAsync
(and exceptionallyAsync
which takes an Executor
).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With