【问题标题】:Java parallel stream using only one thread?Java 并行流仅使用一个线程?
【发布时间】:2014-10-31 14:36:41
【问题描述】:

我正在使用带有并行流的最新 Java 8 lambda 处理数据。 我的代码如下:

ForkJoinPool forkJoinPool = new ForkJoinPool(10);
List<String> files = Arrays.asList(new String[]{"1.txt"}); 
List<String> result = forkJoinPool.submit(() ->
    files.stream().parallel()
        .flatMap(x -> stage1(x)) //at this stage we add more elements to the stream
        .map(x -> stage2(x))
        .map(x -> stage3(x))
        .collect(Collectors.toList())
).get();

流从一个元素开始,但在第二阶段添加更多元素。 我的假设是这个流应该并行运行,但在这种情况下只使用一个工作线程。

如果我从 2 个元素开始(即,我将第二个元素添加到初始列表中),则生成 2 个线程来处理流等等......如果我没有明确地将流提交到ForkJoinPool。

问题是:它是记录在案的行为还是可能在实施中发生变化?有什么方法可以控制这种行为并允许更多线程而不考虑初始列表?

【问题讨论】:

    标签: java parallel-processing java-8 java-stream fork-join


    【解决方案1】:

    您可以尝试 simple-react 中的 LazyFutureStream 或 EagerFutureStream Stream 实现。两个 Stream 都会为每个处理单元创建一个 CompletableFuture,每个处理单元都可以在单独的线程上执行。这可能会导致更高效的处理(取决于您的实际用例和资源)。

    例如

     LazyFutureStream.parallelBuilder(10)
                    .of("1.txt")
                    .flatMap(x -> stage1(x)) 
                    .map(x -> stage2(x))
                    .map(x -> stage3(x))
                    .collect(Collectors.toList());
    

    EagerFutureStream.parallelBuilder(10)
                    .of("1.txt")
                    .flatMap(x -> stage1(x)) 
                    .map(x -> stage2(x))
                    .map(x -> stage3(x))
                    .collect(Collectors.toList());
    

    【讨论】:

      【解决方案2】:

      您观察到的是特定于实现的行为,而不是指定的行为。

      当前的 JDK 8 实现查看最外层流的 Spliterator 并将其用作拆分并行工作负载的基础。由于该示例在原始源流中只有一个元素,因此无法拆分,并且流运行单线程。这适用于flatMap 返回零、一个或仅少数元素的常见(但绝不是唯一)情况,但在它返回大量元素的情况下,它们都是按顺序处理的。事实上,flatMap 函数返回的流被强制进入顺序模式。请参阅ReferencePipeline.java 的第 270 行。

      要做的“显而易见”的事情是使这个流并行,或者至少不强制它是顺序的。这可能会或可能不会改善事情。它很可能会改善某些事情,但会使其他事情变得更糟。这里当然需要一个更好的政策,但我不确定它会是什么样子。

      另请注意,用于强制并行流在您选择的 fork-join 池中运行的技术(通过向其提交运行管道的任务)也是特定于实现的行为。它在 JDK 8 中以这种方式工作,但将来可能会改变。

      【讨论】:

      • 谢谢!这真的让事情变得更清楚了! (我有一种感觉,在当前的开发状态下,java 流更适合更简单(更原子和可控)的任务,您不介意 100% 的效率,而是更喜欢干净简单的解决方案。)
      猜你喜欢
      • 2018-06-21
      • 1970-01-01
      • 2013-04-03
      • 2015-09-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-10-01
      • 1970-01-01
      相关资源
      最近更新 更多