目前我正在阅读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);
}
我不明白为什么第一种方法在并行模式下是错误的,书中没有解释。
请解释。
答案 0 :(得分:6)
javadoc说:
标识值必须是累加器函数的标识。这意味着对于所有t,accumulator.apply(identity,t)等于t。累加器函数必须是关联函数。
在你的第一个例子中显然不是这样的:
5 * x不等于x。
它在并行模式下没有给出相同结果的原因是,在这种模式下,流被分成块,并且对每个块应用缩减,然后减少每个块的结果。因此,您最终会多次乘以5,而在顺序模式下,乘以5只会发生一次。