简体   繁体   中英

CompletableFuture.thenAccept can indeed block

Unlike stated in some blogs(eg 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?

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM