以下是我对Java 8的Stream framework的理解:
虽然有人已经found a way使用自定义线程池和Stream框架的并行执行,但我不能在我的生活中找到任何在Java 8 API中提到的默认Java 8并行流实现将使用ForkJoinPool#commonPool()。 (Collection#parallelStream(),StreamSupport类中的方法,以及API中我不知道的其他可能的并行启用流源。
我只能搜索搜索结果的花絮是这些:
State of the Lambda: Libraries Edition ("Parallelism under the hood")
模糊地提到Stream框架和Fork / Join机制。
Fork / Join机器旨在自动执行此过程。
JEP 107: Bulk Data Operations for Collections
几乎直接声明Collection接口的默认方法#parallelStream()使用Fork / Join实现自身。但仍然没有关于公共池的事。
并行实现基于Java 7中引入的java.util.concurrency Fork / Join实现。
Class Arrays (Javadoc)
直接说明使用公共池的多次。
ForkJoin公共池用于执行任何并行任务。
所以我的问题是:
在哪里说ForkJoinPool#commonPool()用于对从Java 8 API获取的流进行并行操作?
答案 0 :(得分:13)
<强> W.r.t。哪里记录了Java 8并行流使用FJ Framework?
Afaik(Java 1.8u5)在并行流的JavaDoc中没有提到使用常见的ForkJoinPool。
但是在底部的ForkJoin文档中提到了它 http://docs.oracle.com/javase/tutorial/essential/concurrency/forkjoin.html
<强> W.r.t。替换线程池
我的理解是你可以使用自定义的ForkJoinPool(而不是常用的) - 请参阅Custom thread pool in Java 8 parallel stream - ,但不是与ForkJoin实现不同的自定义ThreadPool(我在这里有一个未解决的问题:How to (globally) replace the common thread pool backend of Java parallel streams?)
<强> W.r.t。替换Streams api
您可以结帐https://github.com/nurkiewicz/LazySeq这是一个更像Scala的流实现 - 非常好,非常有趣
PS(w.r.t. ForkJoin和Streams)
如果您有兴趣,我想请注意,我偶然发现了使用FJ池的一些问题,例如,见。
答案 1 :(得分:4)
对于它的价值,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。
答案 2 :(得分:1)
您可以在GrepCode上查看终端操作的源代码。例如,让我们看一下ForEachOp。如您所见,ForEachOp的evaluateParallel方法创建并调用ForEachTask对象,该对象派生自派生自ForkJoinTask的CountedCompleter。