官方文档在哪里说Java的并行流操作使用fork / join?
以下是我对Java 8的Stream框架的理解:
- 东西创造了一个源流
- 该实现负责提供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 。