在Java SDK8中,Collection类附带了一个新方法"parallelStream“。
很明显,这个新方法提供了一种并行使用集合的机制。
但是,我想知道Java是如何实现这种并行性的。潜在的机制是什么?这是一个简单的多线程执行吗?或者,fork/join框架(随Java SDK 7提供)会介入吗?如果答案是两者都不是,那么它是如何工作的,它相对于其他两种机制的优势是什么?
发布于 2015-01-19 00:38:51
查看流的并行方法,您可能想知道并行流使用的线程来自哪里,有多少,以及如何定制进程。并行流在内部使用Runtime.getRuntime().availableProcessors()返回的缺省ForkJoinPool,缺省情况下,它的线程数与处理器的数量一样多。但是您可以使用系统属性java.util.concurrent.ForkJoinPool.common.parallelism更改此池的大小。
并行流在幕后用来并行执行操作的基础设施是Java 7中引入的fork/join框架。为了正确使用它们,对并行流内部机制有一个很好的理解是至关重要的。fork/join框架旨在以递归方式将可并行化的任务拆分成较小的任务,然后组合每个子任务的结果以产生整体结果。它是ExecutorService接口的一个实现,该接口将这些子任务分发给一个名为ForkJoinPool的线程池中的工作线程。
Spliterator代表“可拆分迭代器”。与迭代器一样,拆分器用于遍历源的元素,但它们也被设计为并行执行此操作。尽管在实践中您可能不必开发自己的Spliterator,但了解如何开发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章:并行数据处理和性能。
发布于 2014-07-09 06:45:33
据我所知,不能保证你会得到真正以多线程方式工作的并行流。如果收集可以划分为单独的任务,那么Fork/Join框架将发挥作用,如果不是,那么您将获得串行流。
要检查不同的集合,您可以在每个集合上运行并行流,并从内部执行System.out.println(Thread.currentThread())。输出应类似于: ThreadForkJoinPool.commonPool-worker-%d%
发布于 2014-07-08 22:50:54
但是,我想知道
是如何实现这种并行性的。潜在的机制是什么?这是一个简单的多线程执行吗?或者,fork/join框架(随Java SDK 7提供)会介入吗?如果答案是两者都不是,那么它是如何工作的,它相对于其他两种机制的优势是什么?
据我所知,它基于fork/join框架(随Java SDK 7提供)。
https://stackoverflow.com/questions/24634825
复制相似问题