-3

how is a==b false when running in parallel but when used with combiner it works?

public class test {

 public static int cal(final int i) {
       return 1;
 }
 
 public static void main(String args[]) {

   int a = IntStream.range(0, 3).reduce(0, (abc, cde) -> abc + cal(cde));
   int b = IntStream.range(0, 3).parallel().reduce(0, (abc, cde) -> abc + cal(cde));
   System.out.println(a == b); // false

   int c = List.of(0, 1, 2).stream().parallel().reduce(0, (abc, cde) -> abc + cal(cde), Integer::sum);
   System.out.println(a == c); // true
  }
}
Vijay Babu
  • 33
  • 8

1 Answers1

5

The function passed to reduce is required to be associative.

The accumulator function must be an associative function.

Yours is not.

The behavior of a stream when you break the contract is undefined. In particular, parallel streams may break the stream into arbitrary chunks and combine them in whatever grouping they like, which only works with associative functions. Non-parallel streams generally apply the reducer in one consistent order, but that's not guaranteed by the contract and may change.

Louis Wasserman
  • 191,574
  • 25
  • 345
  • 413