如何减少Java parallelStream中的线程数?

时间:2016-01-06 11:11:36

标签: java multithreading lambda parallel-processing java-stream

我有一个parallelStream()的测试代码,可以将请求发送到服务器机器。

Report report = 
    requestsList.parallelStream()
                .map(request -> freshResultsGenerator.getResponse(request, e2EResultLongBL))
                .map(response -> resultsComparer.compareToBl(response, e2EResultLongBL,
                            astarHistogramsArrayBl, latencyHistogramBl))
                .reduce(null,
                        (sumReport, compare2) ->
                        {
                            if (sumReport == null) {
                                sumReport = new Report();
                            }
                            sumReport.add(compare2);
                            return sumReport;
                        },
                        (report1, report2) ->
                        {
                            Report report3 = new Report();
                            report3.add(report1);
                            report3.add(report2);
                            return report3;
                        });

此计算机的负载太多,很快就会返回HTTP 404错误。

我在Google上找不到答案有两件事:

  1. 如果没有自定义,parallelStream的默认线程数是多少 组?
  2. 如何将工作线程数设置为4?

3 个答案:

答案 0 :(得分:2)

Stream API使用ForkJoinPool来执行并发任务。引用其文档:

  

默认情况下,公共池是使用默认参数构建的,但可以通过设置三个系统属性来控制它们:

     
      
  • java.util.concurrent.ForkJoinPool.common.parallelism - 并行度级别,非负整数   
    ...
  •   

另外

  

可以用给定的目标并行度级构建ForkJoinPool;默认情况下,等于可用处理器的数量。

因此,要自定义线程数,可以将系统属性java.util.concurrent.ForkJoinPool.common.parallelism设置为所需的值:

System.setProperty("java.util.concurrent.ForkJoinPool.common.parallelism", "4")

将工作线程数设置为4.默认情况下,线程数将等于您拥有的处理器数。

答案 1 :(得分:1)

ParallelStream使用ForkJoinPool.commonPool()初始化为核心数 - 1

可以将ForkJoin Executor传递给parallel {here,但执行者必须是一个ForkJoin,这对IO绑定任务来说不是最好的。

答案 2 :(得分:1)

您可以在自定义ForkJoinPool内启动管道,它将用于获取结果:

ForkJoinPool fjp = new ForkJoinPool(2);
System.out.println("My pool: " + fjp);
String result = CompletableFuture.supplyAsync(
    () -> Stream.of("a", "b", "c").parallel()
    .peek(x -> System.out.println(
        ((ForkJoinWorkerThread) Thread.currentThread()).getPool()))
    .collect(Collectors.joining()), fjp).join();
System.out.println(result);

我的StreamEx库添加了一个语法糖方法.parallel(fjp),以简化:

String result = StreamEx.of("a", "b", "c")
    .parallel(fjp)
    .peek(x -> System.out.println(
        ((ForkJoinWorkerThread) Thread.currentThread()).getPool()))
    .collect(Collectors.joining());