官方文档在哪里说Java的并行流操作使用fork / join?

以下是我对Java 8的Stream框架的理解:

  1. 东西创造了一个源流
  2. 该实现负责提供BaseStream#parallel()方法,该方法依次返回可以并行运行其操作的Stream。

虽然有人已经找到了一种方法来使用带有Stream框架并行执行的自定义线程池,但我无法在Java 8 API中找到任何提及默认Java 8并行Stream实现将使用ForkJoinPool#commonPool()的内容 。 ( Collection#parallelStream() , StreamSupport类中的方法,以及API中我不知道的其他可能的并行启用流源)。

我只能搜索搜索结果的花絮是:

  • Lambda的状态:图书馆版(“引擎盖下的并行”)
    模糊地提到Stream框架和Fork / Join机制。

    Fork / Join机器旨在实现此过程的自动化。

  • JEP 107:集合的批量数据操作
    几乎直接声明Collection接口的默认方法#parallelStream()使用Fork / Join实现自身。 但仍然没有关于公共池。

    并行实现基于Java 7中引入的java.util.concurrency Fork / Join实现。

    因此: Collection#parallelStream() 。

  • 类数组(Javadoc)
    直接指出使用公共池的多次。

    ForkJoin公共池用于执行任何并行任务。


所以我的问题是:

在哪里说ForkJoinPool#commonPool()用于从Java 8 API获得的流上的并行操作?

Wrt在哪里记录了Java 8并行流使用FJ Framework?

Afaik(Java 1.8u5)在并行流的JavaDoc中没有提到使用常见的ForkJoinPool。

但是在http://docs.oracle.com/javase/tutorial/essential/concurrency/forkjoin.html底部的ForkJoin文档中提到了它。

Wrt替换线程池

我的理解是你可以使用自定义的ForkJoinPool(而不是常用的) – 参见Java 8并行流中的自定义线程池 – 但不是与ForkJoin实现不同的自定义ThreadPool(我在这里有一个未解决的问题: 如何(全局)替换Java并行流的公共线程池后端? )

Wrt取代了Streams api

你可以结帐https://github.com/nurkiewicz/LazySeq这是一个更像Scala的流实现 – 非常好,非常有趣

PS(wrt ForkJoin和Streams)

如果您有兴趣,我想请注意,我偶然发现了使用FJ池的一些问题,请参阅,例如

  • 嵌套的Java 8并行forEach循环表现不佳。 这种行为有望吗?
  • 在嵌套的Java 8并行流动作中使用信号量可能是DEADLOCK。 这是一个错误吗?

对于它的价值,Java 8 in Action有一章关于并行数据处理和性能 (第7章)。 它说:

“… Stream接口让您有机会在不费力的情况下并行执行数据集合操作。”

“……你将看到Java如何通过使用Java 7中引入的fork / join框架来实现这种神奇的发生,或者更实际的是,并行流如何在引擎盖下工作。”

它在第7.1节中也有一个小旁注:

“并行流在内部使用默认的ForkJoinPool …默认情况下,它具有与处理器一样多的线程,由Runtime.getRuntime().availableProcessors().

“您可以使用系统属性java.util .concurrent.ForkJoinPool.common.parallelism更改此池的大小,如下例所示:”

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

正如评论和其他答案中所提到的,这并不意味着它总是会使用fork / join。

您可以在GrepCode上查看终端操作的源代码。 例如,让我们来看看ForEachOp 。 正如您所见,ForEachOp的evaluateParallel方法创建并调用ForEachTask对象,该对象派生自从ForkJoinTask派生的CountedCompleter 。