Java8的Collection.parallelStream如何工作?

2024-03-05

Collection类带有一个新方法“parallelStream“在 Java SDK 8 中。

显然,这种新方法提供了一种并行消费集合的机制。

但是,我想知道Java是如何实现这种并行性的。其根本机制是什么?它只是多线程执行吗?或者 fork/join 框架(随 Java SDK 7 一起提供)会介入吗?如果答案都不是,那么它是如何工作的以及它相对于其他两种机制的优势是什么?


看了流的并行方法,你可能想知道并行流使用的线程从哪里来,有多少个,以及如何自定义流程。并行流内部使用默认值ForkJoinPool,默认情况下,它具有与处理器一样多的线程,如由Runtime.getRuntime().availableProcessors()。但是您可以使用系统属性更改此池的大小java.util.concurrent.ForkJoinPool.common.parallelism.

并行流在后台用于并行执行操作的基础设施是 Java 7 中引入的 fork/join 框架。为了正确使用它们,充分了解并行流的内部结构至关重要。 fork/join 框架旨在将可并行任务递归地拆分为更小的任务,然后组合每个子任务的结果以生成总体结果。这是一个实现ExecutorService接口,它分发这些 线程池中工作线程的子任务,称为ForkJoinPool.

The Spliterator代表“可分割迭代器”。与迭代器一样,拆分器用于遍历源的元素,但它们也被设计为并行执行此操作。尽管您在实践中可能不必开发自己的 Spliterator,但了解如何开发将使您对并行流的工作原理有更广泛的了解。

将 Stream 拆分为多个部分的算法是一个递归过程。第一步,调用一个方法trySplit在第一个 Spliterator 上调用并生成第二个 Spliterator。然后在步骤 2 中再次调用这两个 Spliterator,总共有 4 个。框架不断调用 Spliterator 上的 trySplit 方法,直到它返回 null 以指示数据 它正在处理的结构不再可分。最后,当所有 Spliterator 都向 trySplit 调用返回 null 时,此递归拆分过程终止。

Spliterator 接口声明的最后一个抽象方法是 features,它返回一个 int 编码 Spliterator 本身的特征集。 Spliterator 客户端可以使用这些特性来更好地控制和优化其使用。他们是:ORDERED, DISTINCT, SORTED, SIZED, NONNULL, IMMUTABLE, CONCURRENT, and SUBSIZED。根据流的具体特征,它实际上可能根本不并行运行。

详细解释这一切的书是:Java 8 实战:Lambda、流和函数式编程 (拉乌尔-加布里埃尔·乌尔玛、马里奥·福斯科和艾伦·麦克罗夫特) https://rads.stackoverflow.com/amzn/click/com/1617291994,来自曼宁。参见第 7 章:并行数据处理和性能.

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Java8的Collection.parallelStream如何工作? 的相关文章

随机推荐