Fork加入池理解

问题描述 投票:1回答:3

我遇到了一个名为ForkJoinPool的java.util.concurrent包中的新类。据我所知,它使用以下方案:

将大任务划分为子任务(fork),当每个任务完成时,收集所有子任务(join),然后合并它。

Fork join pool有一个构造函数public ForkJoinPool(int parallelism)。 从官方文档中我读了以下内容:

通过将自身分成子任务,每个子任务可以由不同的CPU或同一CPU上的不同线程并行执行。

问题是如何设置forkjoinpool的线程数量。

构造函数中的parallelism是指线程数量还是处理器数量。如果是处理器数量,请考虑以下代码:

Runtime.getRuntime().availableProcessors()
return 4

这是否意味着以下ForkJoinPool pool = new ForkJoinPool(8);无效,因为我的电脑只有4个处理器?

代码示例

public static void main(String[] args) throws Exception {

        ForkJoinPool pool = new ForkJoinPool(8);
        final List<String> list = Arrays.asList("dasd","dasd")//for example 300 hundrends strings;
        pool.submit(()->{
            list.parallelStream().forEach(AvailableProc::test);
        }).get();

    }

    public static void test(final String code){
            Thread.sleep(1000);     
            System.out.println(code);
    }
java multithreading
3个回答
2
投票

构造函数中的parallelism是指线程数量还是处理器数量

parallelism参数告诉ForkJoinPool要使用多少个工作线程。默认情况下,它等于可用的处理器数量,这通常是最佳的。当然,你可以在这里设置任何数字,但设置大于处理器的数量最有可能不会受益。

这是否意味着以下ForkJoinPool pool = new ForkJoinPool(8);无效,因为我的PC只有4个处理器?

这取决于你的实际任务。例如,您的代码示例将每秒打印8个字符串:您有8个线程,操作系统将使用context switching在4个处理器上安排所有这些线程。由于大多数时候线程只是等待,并且执行时间非常短,因此每秒可以获得8个字符串。


1
投票

如果过度分配工作线程数,则只需要从CPU内核绑定和取消绑定的线程。这可能会影响性能,也可能不会影响性能,具体取决于您的工作流程(以及线程正在处理的任务被I / O阻止的频率)。

请注意,默认值是CPU核心数,但没有迹象表明它是上限。


0
投票

“此实现将最大运行线程数限制为32767.尝试创建大于最大数量的池会导致IllegalArgumentException。”来自ForkJoinPool - Java8 API doc

© www.soinside.com 2019 - 2024. All rights reserved.