Here is my code:
int count=20; Stream.iterate(4,i->i<count,i->i+1).parallel().forEach(i -> { try { Thread.sleep(new Random().nextInt(2000)); } catch (InterruptedException ignored) { } System.out.println(i); });
I expect this will go parallel, but! When i run it, parallel() seems “dead”, numbers from 4 to 19 comes with a “perfect” sequence which was not i want. So i modified the “iterate” part like this:
.iterate(4,i->i+1).limit(count-4)
There comes fixed, the parallel() works again. So, Why??? The iterate-limit-parallel combo seems too silly. …Or in fact, there may be a reason? please help me. THX!
ps: I print the thread ID, in the first case, that always printing “main”. in the second case, at least 5 threads shows up.
pps: I’ve tried 2000 as a big number during this weird stuck a few minutes ago. now even with several larger num(even using Integer.MAX_VALUE). Still stucks.
Advertisement
Answer
It’s very hard to construct a meaningful spliterator for a stream which is generated by iterate() with 3 arguments. For example, if you have a simple stream of integers from range from 1 to 1000 you can easily split this stream into two streams, one from 1 to 500 and another from 501 to 1000 and process them in parallel. But consider this example:
Stream.iterate(4,i->i<Integer.MAX_VALUE,i->i+ThreadLocalRandom.current().nextInteger())
How would you make this stream parallel? Which number should the second thread start from? There is no way to effectively split this stream into parts without calculating all its elements first.
When you add limit() to the stream you actually buffer the results of the previous stream, so limit() can provide a non-trivial spliterator for it’s internal buffer. However, neither of the streams are guaranteed to do something special in parallel streams, parallel() is just a “recommendation”.