Java8的集合。平行流有效吗?
Collection
类在JavaSDK8中附带了一个新方法“parallelStream
”
显然,这个新方法提供了一种并行使用集合的机制
但是,我想知道Java是如何实现这种并行性的。潜在的机制是什么?它只是一个多线程执行吗?或者fork/join框架(随JavaSDK7一起提供)介入了吗?如果答案都不是,那么它是如何工作的?与其他两种机制相比,它有什么优势
你可以在下面搜索框中键入要查询的问题!
Collection
类在JavaSDK8中附带了一个新方法“parallelStream
”
显然,这个新方法提供了一种并行使用集合的机制
但是,我想知道Java是如何实现这种并行性的。潜在的机制是什么?它只是一个多线程执行吗?或者fork/join框架(随JavaSDK7一起提供)介入了吗?如果答案都不是,那么它是如何工作的?与其他两种机制相比,它有什么优势
# 1 楼答案
据我所知,它基于fork/join框架(JavaSDK7附带)
# 2 楼答案
据我所知,并不能保证你能得到真正以多线程方式工作的并行流。 如果集合可以划分为单独的任务,那么Fork/Join框架将启动,如果不是,那么您将获得串行流
要检查不同的集合,可以在每个和系统上运行并行流。出来println(Thread.currentThread())来自内部的内容。输出应该类似于:Thread[ForkJoinPool.commonPool worker-%d%]
# 3 楼答案
查看流的并行方法,您可能会想知道并行流使用的线程来自哪里,有多少线程,以及如何定制流程。并行流在内部使用默认的
ForkJoinPool
,默认情况下,它的线程数与Runtime.getRuntime().availableProcessors()
返回的处理器数相同。但是,您可以使用系统属性java.util.concurrent.ForkJoinPool.common.parallelism
更改此池的大小并行流在后台用来并行执行操作的基础设施是Java7中引入的fork/join框架。为了正确使用并行流内部结构,对其有一个良好的理解是至关重要的。fork/join框架的设计目的是递归地将一个可并行化的任务拆分为更小的任务,然后将每个子任务的结果组合起来,生成整体结果。它是
ExecutorService
接口的一个实现,它分发这些 线程池中工作线程的子任务,称为ForkJoinPool
Spliterator
代表“可拆分迭代器”与迭代器一样,拆分器用于遍历源的元素,但它们也被设计为并行执行。虽然在实践中您可能不必开发自己的拆分器,但了解如何实现这一点将使您对并行流的工作方式有更广泛的了解将流拆分为多个部分的算法是一个递归过程。在第一步中,在第一个拆分器上调用名为
trySplit
的方法,并生成第二个拆分器。然后在第2步中,这两个拆分器会再次调用它,结果总共是四个。该框架在拆分器上不断调用trySplit方法,直到它返回null以表示数据 它处理的结构不再是可分割的。最后,当所有拆分器向trySplit调用返回null时,这个递归拆分过程终止Spliterator接口声明的最后一个抽象方法是characteristics,它返回一个int编码Spliterator本身的一组特征。Spliterator客户端可以使用这些特性来更好地控制和优化其使用。它们是:
ORDERED
,DISTINCT
,SORTED
,SIZED
、NONNULL
、IMMUTABLE
、CONCURRENT
和SUBSIZED
。根据流的具体特征,它实际上可能根本不会并行运行详细解释这一切的书是:Java 8 in Action: Lambdas, streams, and functional-style programming (Raoul-Gabriel Urma, Mario Fusco, and Alan Mycroft),来自曼宁。见第7章: 并行数据处理和性能