Unlike stated in some blogs(e.g. I can't emphasize this enough: thenAccept()/thenRun() methods do not block) CompletableFuture.thenAccept
can indeed block. Consider the following code, uncommenting the pause
method call will cause thenAccept
to block:
CompletableFuture<String> future = CompletableFuture.supplyAsync(() -> {
log.trace("return 42");
return "42";
});
//pause(1000); //uncommenting this will cause blocking of thenAccept
future.thenAccept((dbl -> {
log.trace("blocking");
pause(500);
log.debug("Result: " + dbl);
}));
log.trace("end");
pause(1000);
Can we be sure that the following will not block? It's my understanding that if the supplyAsync
runs immediately then the thenAccept
could block, no?
CompletableFuture<Void> future = CompletableFuture.supplyAsync(() -> {
return "42";
}).thenAccept((dbl -> {
pause(500);
log.debug("Result: " + dbl);
}));
You are right, thenAccept()
will block if the future is already completed. Also note that when it is not the case, it will cause the thread that completes it to block at the time of completion.
This is why you have thenAcceptAsync()
, which will run your Consumer
in a non-blocking way:
CompletableFuture<Void> future = CompletableFuture.supplyAsync(() -> {
return "42";
}).thenAcceptAsync((dbl -> {
pause(500);
log.debug("Result: " + dbl);
}));
See also Which executor is used when composing Java CompletableFutures?
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