CompletableFuture.thenAccept确实可以挡

CompletableFuture.thenAccept can indeed block

与某些博客中所述不同(例如 I can't emphasize this enough: thenAccept()/thenRun() methods do not blockCompletableFuture.thenAccept 确实可以阻止。考虑以下代码,取消注释 pause 方法调用将导致 thenAccept 阻塞:

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);

我们能确定以下不会阻塞吗?据我了解,如果 supplyAsync 立即运行,那么 thenAccept 可能会阻塞,不是吗?

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

你说得对,thenAccept() 如果 future 已经完成就会阻塞。还要注意,当不是这样的时候,会导致完成它的线程在完成的时候阻塞。

这就是为什么你有 thenAcceptAsync(),它将 运行 你的 Consumer 以非阻塞方式:

CompletableFuture<Void> future = CompletableFuture.supplyAsync(() -> {
    return "42";
}).thenAcceptAsync((dbl -> {
    pause(500);
    log.debug("Result: " + dbl);
}));

另见