在JDK8中,当我使用parallelStream时会产生多少个线程?例如,在代码中:
list.parallelStream().forEach(/** Do Something */);
如果此列表有100000个项目,将产生多少个线程?
另外,每个线程是否都可以处理相同数量的项目,还是随机分配的?
在JDK8中,当我使用parallelStream时会产生多少个线程?例如,在代码中:
list.parallelStream().forEach(/** Do Something */);
如果此列表有100000个项目,将产生多少个线程?
另外,每个线程是否都可以处理相同数量的项目,还是随机分配的?
Answers:
Oracle并行流的实现[1]使用当前线程,此外,如果需要,还使用构成默认派生连接池的线程,该线程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
完全无用的行为在内部使用替代项(有关详细信息,请参见此处)。
Stream
API的使用ForkJoinPool
是一个实现细节。因此,这两种解决方案都可以与Oracle当前的实现一起使用,但不能保证在任何地方都可以使用。