Java 和竞赛:
- Java 始终处于促进并发编程的最前沿,自 1996 年以来提供本机线程支持,并不断发展以包含 java.util.concurrent 和 fork-join 框架等库。
流和并行性:
- 随着 Java 8 中流的引入,通过一次调用parallel()方法就可以轻松地并行化操作。然而,即使很容易,编写正确且快速的并发程序仍然具有挑战性。
性能和失败:
- 不小心的流管道并行化可能会导致性能和活动失败(程序无法完成)。给出的示例表明,并行化流可能会导致 CPU 使用率显着增加,但没有明显的结果。
启发法和限制:
- 如果用于划分工作的启发式方法不合适,流并行化可能会失败,特别是在像 Stream.iterate 和 limit 这样的操作中,计算额外元素的成本可能非常高。
理想的数据结构:
ArrayList、HashMap、HashSet、ConcurrentHashMap、数组和范围上的流更适合并行化,因为可以轻松地在线程之间划分工作并且具有良好的引用局部性。
终端操作:
- 并行执行的有效性还取决于流的终端操作。归约操作(例如reduce、min、max、count和sum)以及短路操作(例如anyMatch、allMatch和noneMatch)最适合并行性。
严格规格:
- 并行管道中使用的函数必须是关联的、互不干扰的和无状态的。违反这些规则可能会导致不正确的结果或灾难性的失败。
执行订单:
- 并行化管道可能会使输出变得混乱,并且可能需要像 forEachOrdered 这样的操作来保持顺序。
合理的并行性:
- 只有在有充分理由的情况下才并行化流。并行性不足可能会导致崩溃或性能不佳。始终在并行化之前和之后测量性能,以确保它是有益的。
效果示例:
- 一个简单的例子表明,并行化 π(n) 计算将执行时间从 31 秒减少到 9.2 秒,这表明并行性在某些场景下是高效的。
SplitableRandom 的使用:
- 对于并行随机数流,更喜欢 SplittableRandom 而不是 ThreadLocalRandom 或 Random,因为它是专门为此用途而设计的,并提供更好的性能。
结论:
- 如果没有充分的理由相信这样做可以保持计算精度并提高速度,请勿尝试并行化流管道。在将并行性应用于生产代码之前,进行严格的测试以验证并行性是否合理。
示例
1.顺序与顺序流示例并行
- 此示例演示了顺序流和并行流之间的性能差异。 ParallelStreamExample.java
2.低效使用parallel()的示例
- 此示例展示了并行化如何导致意外行为。 InefficientParallelStream.java
3.高效使用parallel()的示例
- 这个例子展示了并行化实际上可以提高性能的情况。 高效并行流,java
4.并行流的安全缺陷示例
- 此示例演示了并行使用时,实施不当的归约操作可能会失败。 ParallelStreamSafetyExample.java
5.并行流的 SplittableRandom 示例
- 此示例演示了如何在并行流中使用 SplittableRandom 以获得更好的性能。 SplittableRandomExample.java
这些示例有助于说明并行化的有用之处,并且还显示了不加区别地使用 parallel() 的潜在风险。
以上是项目 进行并行流时要小心的详细内容。更多信息请关注PHP中文网其他相关文章!