【发布时间】:2015-09-26 17:28:58
【问题描述】:
在 Java 8 中,并行流是否可能给出与串行流不同的结果?根据我的信息,并行流与串行流相同,只是分为多个子流。这是速度的问题。对元素的所有操作都已完成,子流的结果最后合并。最后,我认为并行和串行流的操作结果应该相同。所以我的问题是,这段代码有没有可能给我一个不同的结果?如果可能,为什么会发生?
int[] i = {1, 2, 5, 10, 9, 7, 25, 24, 26, 34, 21, 23, 23, 25, 27, 852, 654, 25, 58};
Double serial = Arrays.stream(i).filter(si -> {
return si > 5;
}).mapToDouble(Double::new).map(NewClass::add).reduce(Math::atan2).getAsDouble();
Double parallel = Arrays.stream(i).filter(si -> {
return si > 5;
}).parallel().mapToDouble(Double::new).map(NewClass::add).reduce(Math::atan2).getAsDouble();
System.out.println("serial: " + serial);
System.out.println("parallel: " + parallel);
public static double add(double i) {
return i + 0.005;
}
结果是:
serial: 3.6971567726175894E-23
parallel: 0.779264049587662
【问题讨论】:
-
减少使用
atan2完全没有意义。例如,它不是关联的。 -
仅供参考:
si -> { return si > 5; }应该只是si -> si > 5,并且您希望在parallel()之后 进行过滤。 -
不,问题是reduce 需要一个关联函数
-
@Andreas,你可以把
.parallel()放在流启动和终端操作之间的任意位置,结果是一样的。 -
调用
.mapToDouble(Double::new)将每个int扩大到double,将它们装箱为Double对象,然后将它们拆箱为double值。如果您想将int转换为double,.mapToDouble(i->i)会更直接,跳过对象创建。但更简单的是.asDoubleStream()...而且,如果您真的需要装箱值,请使用Double::valueOf而不是Double::new。
标签: java lambda parallel-processing java-8 java-stream