【问题标题】:How Java8's Collection.parallelStream works?Java8 的 Collection.parallelStream 是如何工作的?
【发布时间】:2014-07-08 14:44:46
【问题描述】:

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

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

但是,我想知道 Java 是如何实现这种并行性的。底层机制是什么?它只是一个多线程执行吗?还是 fork/join 框架(Java SDK 7 附带)介入?如果答案都不是,那么它是如何工作的,与其他两种机制相比,它有什么优势?

【问题讨论】:

  • 你可以查看源代码,你知道...

标签: java multithreading parallel-processing java-8 java-stream


【解决方案1】:

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

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

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

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

Spliterator 接口声明的最后一个抽象方法是characteristics,它返回一个int 编码Spli​​terator 本身的特征集。 Spliterator 客户端可以使用这些特性来更好地控制和优化其使用。它们是:ORDEREDDISTINCTSORTEDSIZEDNONNULLIMMUTABLECONCURRENTSUBSIZED。根据流的具体特性,它实际上可能根本不会并行运行。

详细解释这一切的书是:Java 8 in Action: Lambdas, streams, and functional-style programming (Raoul-Gabriel Urma, Mario Fusco, and Alan Mycroft),来自曼宁。参见第 7 章: 并行数据处理和性能

【讨论】:

    【解决方案2】:

    据我所知,不能保证您会获得真正执行多线程方式的并行流。 如果collection可以分成单独的task,那么Fork/Join框架就会启动,如果没有,那么你将得到serial stream。

    要检查不同的集合,您可以在每个集合上运行并行流,并从内部运行 System.out.println(Thread.currentThread()) 一些东西。输出应该类似于:Thread[ForkJoinPool.commonPool-worker-%d%]

    【讨论】:

      【解决方案3】:

      但是,我想知道 Java 是如何实现这种并行性的。底层机制是什么?它只是一个多线程执行吗?或者确实 fork/join 框架(Java SDK 7 附带)介入?如果答案是 也不是,它是如何工作的,它有什么优势 其他两种机制?

      据我所知,它基于 fork/join 框架(随 Java SDK 7 提供)。

      【讨论】:

        猜你喜欢
        • 2018-02-03
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-10-15
        • 2019-03-04
        • 2017-07-24
        • 2016-11-13
        相关资源
        最近更新 更多