java 并行流水线_Java 将顺序流转换为并行流

本文介绍了如何在 Java 中将顺序流转换为并行流,包括使用 Collection 的 stream 和 parallelStream 方法,以及 BaseStream 的 sequential 和 parallel 方法。通过示例代码展示了在创建流、操作流过程中转换流的方式,同时提醒了在并行流和顺序流之间转换需要注意的潜在问题和陷阱。
摘要由CSDN通过智能技术生成

Java 将顺序流转换为并行流,无论默认情况如何,用户希望创建顺序流(sequential stream)或并行流(parallel stream)。既可以使用 Collection 接口定义的 stream 或 parallelStream 方法,也可以使用 BaseStream 接口定义的 sequential 或 parallel 方法。

Java 将顺序流转换为并行流 问题描述

无论默认情况如何,用户希望创建顺序流(sequential stream)或并行流(parallel stream)。

Java 将顺序流转换为并行流 解决方案

既可以使用 Collection 接口定义的 stream 或 parallelStream 方法,也可以使用 BaseStream 接口定义的 sequential 或 parallel 方法。

Java 将顺序流转换为并行流 具体实例

默认情况下,Java 创建的流都是顺序流。在 BaseStream 接口(Stream 的父接口)中,可以通过 isParallel 方法判断流是否采用并行方式执行。

从例 9-1 可以看到,所有采用标准机制创建的流都是顺序流。

例 9-1 创建顺序流(JUnit 测试的一部分)

如果数据源为集合,可以通过 parallelStream 方法返回一个可能的并行流,如例 9-2 所示。

例 9-2 parallelStream 方法的应用

之所以强调“可能的”,是因为 parallelStream 方法在某些情况下也会返回顺序流,但默认返回的是并行流。Javadoc 指出,仅当创建自定义 spliterator 时才会返回顺序流,不过这种情况相当罕见。4

4毋庸置疑,这是一个有趣的话题。不过受篇幅所限,本书不对此做讨论。

如例 9-3 所示,也可以通过在现有流上使用 parallel 方法来创建并行流。

例 9-3 在流上使用 parallel 方法

与 parallel 方法相对的是 sequential 方法,它将返回顺序流,如例 9-4 所示。

例 9-4 将并行流转换为顺序流

不过转换时需谨慎行事,否则可能落入陷阱。假设我们计划创建一个流水线(pipeline),其中一部分处理可以并行地完成,而其他处理仍然按顺序执行。那么,我们很容易写出如例 9-5 所示的代码。

例 9-5 并行流到顺序流的切换(与预期结果不同)

❶ 请求并行流

❷ 先切换为顺序流,再排序

上述代码的含义不难理解:先将所有数字倍增,再排序。由于倍增函数是无状态(stateless)且关联的(associative),采用并行操作可谓顺理成章。然而,排序本质上属于顺序操作 5。

5可以这样理解:使用并行流排序意味着将区间划分为若干相等的部分,然后分别对每部分排序,再尝试将所有经过排序的子区间合并在一起。那么从整体来看,最终的输出其实并没有实现排序。

在本例中,peek 方法用于显示进行处理的线程的名称,程序在调用 parallelStream 方法之后、sequential 方法之前调用 peek。输出如下:

可以看到,main 线程完成了所有的处理。换言之,尽管调用了 parallelStream 方法,但返回的仍然是顺序流。这是什么原因呢?读者或许还记得,流在达到终止表达式(terminal expression)前不会进行任何操作,即在达到终止表达式时才会评估流的状态。在本例中,由于 collect 方法之前最后调用的是 sequential 方法,程序将返回顺序流,并对元素做相应处理。

流在执行时既可以是并行的,也可以是顺序执行的。parallel 或 sequential 方法能有效地设置或撤销设置一个布尔值,并在达到终止表达式时进行检查。

如果确有必要以并行方式处理部分流,而以顺序方式处理流的其他部分,建议使用两个单独的流。虽然这样处理也存在不少问题,但目前尚无更好的解决方案。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值