Stream 在顺序模式下工作,但在并行模式下有问题
Stream works on sequential, but buggy in parallel mode
目前我正在阅读一本Java 8 Lambdas: Pragmatic Functional Programming(非常有趣且写得很好的书,没有任何补充)。
第六章后有练习:
The code multiplies every number in a list together and multiplies the
result by
5. This works fine sequentially, but has a bug when running in parallel.
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);
}
我不明白为什么第一种方法在并行模式下有问题,而且书中没有解释。
请解释一下。
javadoc 说:
The identity value must be an identity for the accumulator function. This means that for all t, accumulator.apply(identity, t) is equal to t. The accumulator function must be an associative function.
在您的第一个示例中显然不是这种情况:
5 * x 不等于 x。
它在并行模式下没有给出相同结果的原因是,在这种模式下,流被分成块,对每个块应用归约,然后对每个块的结果进行归约.所以你最终乘以 5 几次,而在顺序模式下,乘以 5 只发生一次。
目前我正在阅读一本Java 8 Lambdas: Pragmatic Functional Programming(非常有趣且写得很好的书,没有任何补充)。
第六章后有练习:
The code multiplies every number in a list together and multiplies the result by 5. This works fine sequentially, but has a bug when running in parallel.
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);
}
我不明白为什么第一种方法在并行模式下有问题,而且书中没有解释。
请解释一下。
javadoc 说:
The identity value must be an identity for the accumulator function. This means that for all t, accumulator.apply(identity, t) is equal to t. The accumulator function must be an associative function.
在您的第一个示例中显然不是这种情况:
5 * x 不等于 x。
它在并行模式下没有给出相同结果的原因是,在这种模式下,流被分成块,对每个块应用归约,然后对每个块的结果进行归约.所以你最终乘以 5 几次,而在顺序模式下,乘以 5 只发生一次。