0

I have following code which prints elements of a list using parallel stream:

List<Integer> l = List.of(0,1,2,3,4,5,6,7,8,9);
for (int j = 0; j < 5; j++) {
    l.parallelStream().forEach(i->System.out.print(i+" "));
    System.out.println();
}

Output:

6 5 2 8 4 3 9 7 0 1 
6 5 8 9 2 7 4 1 0 3 
6 5 8 9 7 2 4 3 0 1 
6 5 8 9 7 1 0 4 3 2 
6 5 1 0 4 3 2 9 7 8 

Why the parallel stream starts at 6 most of the times?
Why not start at 0? Why not at mid?

the Hutt
  • 16,980
  • 2
  • 14
  • 44
  • how many cpu cores do you have? – Arthurofos Apr 24 '21 at 10:46
  • 2
    That's just how race conditions sometimes work out. --- Why would you expect "mid"? Do you believe it only does 2 threads? If it only split the list into 2 chunks, then `0,1,2,3,4` would always come out in that order, given that a thread would be processing a sublist in order. The fact the e.g. `0,1` is sometimes `1,0` would indicate that the two values are printed by different threads, i.e. that code is likely running 10 threads. You could print the thread name to see for yourself how many threads are used: `forEach(i->System.out.print(i+"("+Thread.currentThread().getName()+") "))` – Andreas Apr 24 '21 at 10:47
  • @Arthurofos `Runtime.getRuntime().availableProcessors()` returns 4. @Andreas I think the list is being split such that it starts with 6 most of the times. May be because of spliterator? – the Hutt Apr 24 '21 at 11:39

1 Answers1

0

The list is being split and processing starts using threads from the common pool. Changing your code to print the current thread name shows that the main calling thread also processes from the split list and it's results often appear ahead of common pool threads - presumably as there is a small lag before common threads start processing first entry:

List<Integer> l = List.of(0,1,2,3,4,5,6,7,8,9);
for (int j = 0; j < 5; j++) {
    l.parallelStream().forEach(i->System.out.println(Thread.currentThread()+" i="+i));
    System.out.println();
}

On my machine ALL output came from main thread first go:

Thread[main,5,main] i=6
Thread[main,5,main] i=5
Thread[main,5,main] i=8
Thread[main,5,main] i=9
Thread[main,5,main] i=7
Thread[main,5,main] i=2
Thread[main,5,main] i=4
Thread[main,5,main] i=3
Thread[main,5,main] i=1
Thread[main,5,main] i=0

But on subsequent runs the work was more balanced with the common pool:

Thread[main,5,main] i=6
Thread[main,5,main] i=5
Thread[main,5,main] i=8
Thread[main,5,main] i=9
Thread[main,5,main] i=7
Thread[ForkJoinPool.commonPool-worker-5,5,main] i=2
Thread[ForkJoinPool.commonPool-worker-5,5,main] i=4
Thread[ForkJoinPool.commonPool-worker-5,5,main] i=3
Thread[ForkJoinPool.commonPool-worker-5,5,main] i=1
Thread[ForkJoinPool.commonPool-worker-5,5,main] i=0

Thread[main,5,main] i=6
Thread[main,5,main] i=5
Thread[ForkJoinPool.commonPool-worker-5,5,main] i=2
Thread[main,5,main] i=8
Thread[main,5,main] i=9
Thread[ForkJoinPool.commonPool-worker-7,5,main] i=1
Thread[ForkJoinPool.commonPool-worker-7,5,main] i=0
Thread[main,5,main] i=7
Thread[ForkJoinPool.commonPool-worker-5,5,main] i=4
Thread[ForkJoinPool.commonPool-worker-3,5,main] i=3
DuncG
  • 12,137
  • 2
  • 21
  • 33