在Java8中,并行流中产生了多少线程?

在Java8中,并行流中产生了多少线程?,java,multithreading,java-8,java.util.concurrent,Java,Multithreading,Java 8,Java.util.concurrent,在JDK8中,使用parallelStream时生成了多少线程?例如,在代码中: list.parallelStream().forEach(/** Do Something */); 如果此列表有100000个项目,将生成多少个线程 另外,每个线程都有相同数量的项目要处理还是随机分配?Oracle的并行流实现[1]使用当前线程,此外,如果需要,还使用组成默认fork join池的线程ForkJoinPool.commonPool(),它的默认大小小于CPU的内核数 可以使用此属性更改公用池的

在JDK8中,使用parallelStream时生成了多少线程?例如,在代码中:

list.parallelStream().forEach(/** Do Something */);
如果此列表有100000个项目,将生成多少个线程


另外,每个线程都有相同数量的项目要处理还是随机分配?

Oracle的并行流实现[1]使用当前线程,此外,如果需要,还使用组成默认fork join池的线程
ForkJoinPool.commonPool()
,它的默认大小小于CPU的内核数

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

-Djava.util.concurrent.ForkJoinPool.common.parallelism=8
或者,您可以使用自己的池:

ForkJoinPool myPool = new ForkJoinPool(8);
myPool.submit(() ->
    list.parallelStream().forEach(/* Do Something */);
).get();
关于顺序,作业将在线程可用时立即执行,没有特定的顺序


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

虽然@uraimo是正确的,但答案取决于“做点什么”。parallel.streams API使用CountedCompleter类,它有一些有趣的问题。由于F/J框架不使用单独的对象来保存结果,长链可能会导致OOME。此外,这些长链有时会导致堆栈溢出。这些问题的答案是使用我在文章中指出的对话技巧


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

@assylias回答得很好。也许值得补充的是,如果任务数量足够小,并行流实际上可能会在主线程中运行。应该注意的是,
stream
API使用的
ForkJoinPool
是一个实现细节。因此,这两种解决方案都适用于Oracle当前的实施,但不能保证在任何地方都能使用。