有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

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) 个答案

  1. # 1 楼答案

    如果dispatcher只有一个线程,而该线程被阻塞、死锁等,那么整个actor系统就会突然停止。对于每个任务的线程,这不会发生