在Java 8中并行生成了多少个线程?

时间:2015-06-12 11:54:50

标签: java multithreading java-8 java.util.concurrent

在JDK8中,当我使用parallelStream时会产生多少个线程?例如,在代码中:

list.parallelStream().forEach(/** Do Something */);

如果此列表包含100000个项目,将生成多少个线程?

此外,每个线程都可以获得相同数量的项目,还是随机分配?

2 个答案:

答案 0 :(得分:53)

并行流的Oracle实现[1]使用当前线程,除此之外,如果需要,还使用组成默认fork连接池ForkJoinPool.commonPool()的线程,它具有默认大小等于比CPU核心数少一个。

可以使用此属性更改公共池的默认大小:

-Djava.util.concurrent.ForkJoinPool.common.parallelism=8

或者,您可以使用自己的游泳池:

ForkJoinPool myPool = new ForkJoinPool(8);
myPool.submit(() ->
    list.parallelStream().forEach(/* Do Something */);
).get();

关于订单,只要线程可用,就会立即执行作业,无特定顺序。

正如@Holger所正确指出的,这是一个特定于实现的细节(文档底部只有one vague reference),这两种方法都适用于Oracle的JVM,但绝对不能保证工作在其他供应商的JVM上,该属性不能存在于非Oracle实现中,Streams甚至无法使用ForkJoinPool内部呈现替代方案,而ForkJoinTask.fork的行为完全无用(see here关于此的详细信息)。

答案 1 :(得分:3)

虽然@uraimo是正确的,但答案完全取决于“Do Something”的作用。 parallel.streams API使用CountedCompleter类,它有一些有趣的问题。由于F / J框架不使用单独的对象来保存结果,因此长链可能会导致OOME。这些长链有时也会导致堆栈溢出。这些问题的答案是我在this article.

中指出的使用Paraquential技术

另一个问题是在使用嵌套并行forEach时创建过多的线程。