Stream在顺序模式下工作,但在并行模式下工作

时间:2015-03-02 20:10:07

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

目前我正在阅读Java 8 Lambdas: Pragmatic Functional Programming(非常有趣且写得很好的书,没有。)。

在第6章之后有一个练习:

  

代码将列表中的每个数字相乘并乘以   结果   这顺序工作正常,但在并行运行时有一个错误。

public static int multiplyThrough(List<Integer> linkedListOfNumbers) {
    return linkedListOfNumbers.parallelStream()
                       .reduce(5, (acc, x) -> x * acc);
}

解决方案:

public static int multiplyThrough(List<Integer> numbers) {
    return 5 * numbers.parallelStream()
                      .reduce(1, (acc, x) -> x * acc);
}

我不明白为什么第一种方法在并行模式下是错误的,书中没有解释。

请解释。

1 个答案:

答案 0 :(得分:6)

javadoc说:

  

标识值必须是累加器函数的标识。这意味着对于所有t,accumulator.apply(identity,t)等于t。累加器函数必须是关联函数。

在你的第一个例子中显然不是这样的:

5 * x不等于x。

它在并行模式下没有给出相同结果的原因是,在这种模式下,流被分成块,并且对每个块应用缩减,然后减少每个块的结果。因此,您最终会多次乘以5,而在顺序模式下,乘以5只会发生一次。