Completed Future.thenAccept can really block

Unlike stated on some blogs (for example, I can’t emphasize this enough: the thenAccept () / thenRun () methods do not block ) CompletableFuture.thenAccept can really be blocked. Consider the following code, uncommenting a call to the pause method will cause a thenAccept lock:

 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 be blocked? I understand that if supplyAsync starts immediately, then thenAccept may block, no?

 CompletableFuture<Void> future = CompletableFuture.supplyAsync(() -> { return "42"; }).thenAccept((dbl -> { pause(500); log.debug("Result: " + dbl); })); 
+5
source share
1 answer

You are right, thenAccept() block if the future is already completed. Also note that when this is not the case, it will cause the thread to complete its block at the time of termination.

This is why you have thenAcceptAsync() , which will run your Consumer 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 compiling Java CompletedFutures?

+6
source

All Articles