Java 8 中的 parallelStream 中产生了多少线程?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/30802463/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How many threads are spawned in parallelStream in Java 8?
提问by SinnerShanky
In JDK8, how many threads are spawned when i'm using parallelStream? For instance, in the code:
在 JDK8 中,当我使用 parallelStream 时会产生多少线程?例如,在代码中:
list.parallelStream().forEach(/** Do Something */);
If this list has 100000 items, how many threads will be spawned?
如果此列表有 100000 个项目,将产生多少个线程?
Also, do each of the threads get the same number of items to work on or is it randomly allotted?
此外,每个线程是否获得相同数量的项目来处理还是随机分配?
回答by Umberto Raimondi
The Oracle's implementation[1] of parallel stream uses the current thread and in addition to that, if needed, also the threads that compose the default fork join pool ForkJoinPool.commonPool()
, which has a default size equal to one less than the number of cores of your CPU.
Oracle 的并行流实现 [1] 使用当前线程,此外,如果需要,还使用构成默认 fork join pool 的线程ForkJoinPool.commonPool()
,其默认大小等于 CPU 的内核数少 1 .
That default size of the common pool can be changed with this property:
可以使用此属性更改公共池的默认大小:
-Djava.util.concurrent.ForkJoinPool.common.parallelism=8
Alternatively, you can use your own pool:
或者,您可以使用自己的池:
ForkJoinPool myPool = new ForkJoinPool(8);
myPool.submit(() ->
list.parallelStream().forEach(/* Do Something */);
).get();
Regarding the order, jobs will be executed as soon as a thread is available, in no specific order.
关于顺序,只要有线程可用,就会立即执行作业,没有特定的顺序。
As correctly pointed out by @Holger this is an implementation specific detail (with just one vague referenceat the bottom of a document), both approaches will work on Oracle's JVM but are definitely not guaranteed to work on JVMs from other vendors, the property could not exist in a non-Oracle implementation and Streams could not even use a ForkJoinPool
internally rendering the alternative based on the behavior of ForkJoinTask.fork
completely useless (see herefor details on this).
正如@Holger 正确指出的那样,这是一个特定于实现的细节(文档底部只有一个模糊的参考),这两种方法都适用于 Oracle 的 JVM,但绝对不能保证适用于其他供应商的 JVM,该属性可能不存在于非 Oracle 实现中,Streams 甚至无法使用ForkJoinPool
基于ForkJoinTask.fork
完全无用行为的内部渲染替代方案(有关详细信息,请参见此处)。
回答by edharned
While @uraimo is correct, the answer depends on exactly what "Do Something" does. The parallel.streams API uses the CountedCompleter Class which has some interesting problems. Since the F/J framework does not use a separate object to hold results, long chains may result in an OOME. Also those long chains can sometimes cause a Stack Overflow. The answer to those problems is the use of the Paraquential technique as I pointed out in this article.
虽然@uraimo 是正确的,但答案完全取决于“做某事”的作用。parallel.streams API 使用 CountedCompleter 类,它有一些有趣的问题。由于 F/J 框架不使用单独的对象来保存结果,因此长链可能会导致 OOME。此外,那些长链有时会导致堆栈溢出。正如我在本文中指出的那样,这些问题的答案是使用 Paraquential 技术。
The other problem is excessive thread creation when using nested parallel forEach.
另一个问题是在使用嵌套并行 forEach 时创建过多的线程。