java为什么ForkJoinPool使用ThreadPerTaskExecutor?
我们在双CPU环境下运行Java中的Akka应用程序,并观察到每个tell
都会启动一个新线程,而不是将它们从池中取出。Akka默认调度程序使用ForkJoinPool
作为默认执行器。在CompletableFuture
代码中有以下逻辑:
private static final boolean useCommonPool =
(ForkJoinPool.getCommonPoolParallelism() > 1);
private static final Executor asyncPool = useCommonPool ?
ForkJoinPool.commonPool() : new ThreadPerTaskExecutor();
static final class ThreadPerTaskExecutor implements Executor {
public void execute(Runnable r) { new Thread(r).start(); }
}
commonPoolParallelism
的值来自Runtime.getRuntime().availableProcessors() - 1
(如果未指定JVM属性)-ForkJoinPool.makeCommonPool()
因此,在我们只有两个CPU的情况下,根本不使用ForkJoinPool
。默认情况下,它使用ThreadPerTaskExecutor
。我知道我们可以忽略这一点(我们做到了,这会导致性能显著提高)。但这让我想知道为什么会这样?为什么每次启动新线程都比重用池中的一个线程要好,哪怕是一个CPU(不提这两个)?为什么这是ForkJoinPool
的默认行为
# 1 楼答案
如果dispatcher只有一个线程,而该线程被阻塞、死锁等,那么整个actor系统就会突然停止。对于每个任务的线程,这不会发生