ForkJoinPool.commonPool() 和 new ForkJoinPool(availableCPU - 1) 有什么区别?
What is the difference between ForkJoinPool.commonPool() and new ForkJoinPool(availableCPU - 1)?
在我的代码中,我有一个 class 包含一个静态最终变量
private static final ForkJoinPool pool = new ForkJoinPool(availableCPUs - 1);
我有一个很长的 运行 任务提交到池中,它会占用所有 CPU 资源。提交的任何其他任务都将挂起。
但是,当我切换到创建公共池时
private static final ForkJoinPool pool = ForkJoinPool.commonPool();
所有任务均可提交执行
我只是想知道这两段代码之间有什么区别。 commonPool()
仍然调用 new ForkJoinPool()
并传递 availableCPUs - 1
我还注意到 commonPool()
使用 SafeForkJoinWorkerThreadFactory
类型的工厂,而 new ForkJoinPool()
使用 ForkJoinPool$DefaultForkJoinWorkerThreadFactory
。这重要吗?
非常感谢!
The common pool is by default constructed with default parameters.
Creates a ForkJoinPool
with parallelism equal to Runtime.availableProcessors()
, using the default thread factory, no UncaughtExceptionHandler, and non-async LIFO processing mode.
那么是什么让您认为 new ForkJoinPool(availableCPUs - 1)
和 ForkJoinPool.commonPool()
会是相同大小的池?
如果你只有 2 个 CPU,那么 availableCPUs - 1
意味着你正在创建一个线程池,即它一次只能处理一个任务,所以一个 long-运行 任务将阻止所有其他任务。
但是对于 2 个 CPU,availableProcessors()
意味着您将获得一个带有 2 个线程的公共池,即它可以在处理单个 long-运行 任务的同时处理其他任务。
我想我明白了。
ForkJoin 维护两种类型的队列:一种是通用入站队列,另一种是针对每个工作线程的工作线程队列。所有工作线程都将首先从通用入站队列中获取并填充它们的工作线程。当一个工作线程完成其工作队列中的所有任务后,它会尝试从其他工作线程窃取。如果没有其他任务可以从其他工作线程窃取,工作线程将再次从通用入站队列中获取。
但是,有了common pool,主线程也会帮助处理任务。主线程虽然没有工作队列。因此,在完成一个任务后,主线程将能够从一般入站队列中获取。
因为默认情况下,ForkJoin 队列是 LIFO,主线程将能够获取最后提交的任务。
在我的代码中,我有一个 class 包含一个静态最终变量
private static final ForkJoinPool pool = new ForkJoinPool(availableCPUs - 1);
我有一个很长的 运行 任务提交到池中,它会占用所有 CPU 资源。提交的任何其他任务都将挂起。 但是,当我切换到创建公共池时
private static final ForkJoinPool pool = ForkJoinPool.commonPool();
所有任务均可提交执行
我只是想知道这两段代码之间有什么区别。 commonPool()
仍然调用 new ForkJoinPool()
并传递 availableCPUs - 1
我还注意到 commonPool()
使用 SafeForkJoinWorkerThreadFactory
类型的工厂,而 new ForkJoinPool()
使用 ForkJoinPool$DefaultForkJoinWorkerThreadFactory
。这重要吗?
非常感谢!
The common pool is by default constructed with default parameters.
Creates a
ForkJoinPool
with parallelism equal toRuntime.availableProcessors()
, using the default thread factory, no UncaughtExceptionHandler, and non-async LIFO processing mode.
那么是什么让您认为 new ForkJoinPool(availableCPUs - 1)
和 ForkJoinPool.commonPool()
会是相同大小的池?
如果你只有 2 个 CPU,那么 availableCPUs - 1
意味着你正在创建一个线程池,即它一次只能处理一个任务,所以一个 long-运行 任务将阻止所有其他任务。
但是对于 2 个 CPU,availableProcessors()
意味着您将获得一个带有 2 个线程的公共池,即它可以在处理单个 long-运行 任务的同时处理其他任务。
我想我明白了。
ForkJoin 维护两种类型的队列:一种是通用入站队列,另一种是针对每个工作线程的工作线程队列。所有工作线程都将首先从通用入站队列中获取并填充它们的工作线程。当一个工作线程完成其工作队列中的所有任务后,它会尝试从其他工作线程窃取。如果没有其他任务可以从其他工作线程窃取,工作线程将再次从通用入站队列中获取。
但是,有了common pool,主线程也会帮助处理任务。主线程虽然没有工作队列。因此,在完成一个任务后,主线程将能够从一般入站队列中获取。
因为默认情况下,ForkJoin 队列是 LIFO,主线程将能够获取最后提交的任务。