Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to restrict a Stream to run sequentially, and prevent it from running in parallel?

I have a method that returns a stream that is generated from a custom spliterator; the spliterator is not tread safe. Since the spliterator is not tread safe, and it maintains state, I want to prevent it from running in parallel. Is there a way to prevent the returned stream from running in parallel?

I have not been able to find any documentation or examples that do this. I did find a sequential() method on the BaseStream class, but that does not appear to prevent a user from then calling parallel() to get a parallel stream.

like image 729
Mike Rylander Avatar asked Nov 20 '15 20:11

Mike Rylander


People also ask

How do you maintain order in parallel stream?

Note: If we want to make each element in the parallel stream to be ordered, we can use the forEachOrdered() method, instead of the forEach() method.

How do you control threads in a parallel stream?

In case of Parallel stream,4 threads are spawned simultaneously and it internally using Fork and Join pool to create and manage threads. Parallel streams create ForkJoinPool instance via static ForkJoinPool. commonPool() method.

When should you avoid parallel stream?

Similarly, don't use parallel if the stream is ordered and has much more elements than you want to process, e.g. This may run much longer because the parallel threads may work on plenty of number ranges instead of the crucial one 0-100, causing this to take very long time.

What is the difference between sequential stream and parallel stream?

stream() works in sequence on a single thread with the println() operation. list. parallelStream(), on the other hand, is processed in parallel, taking full advantage of the underlying multicore environment. The interesting aspect is in the output of the preceding program.


1 Answers

Parallel stream calls trySplit() method of your spliterator to split your task to the several parts. It's absolutely legit to return null from trySplit() saying that "I refuse to split". In this case the stream created from your spliterator will be executed sequentially even if .parallel() was explicitly called.

However in general you may provide at least a limited parallelism extending the AbstractSpliterator class. It provides default trySplit() implementation which reads some input elements calling your tryAdvance() method, storing them into array and returning the spliterator on that array, so this part can be processed separately and totally independent on your spliterator. This is "poor man" parallelization, but still may improve the speed if the downstream pipeline operations are time consuming.

Finally note that in most simple cases Spliterator implementation should not be thread safe. If you provide your own efficient trySplit() implementation, it's guaranteed that the original spliterator and the newly created spliterator will be processed in totally independent manner. So if you don't modify the shared state in prefix and suffix spliterator after splitting, you should not care about thread-safety.

like image 102
Tagir Valeev Avatar answered Sep 28 '22 09:09

Tagir Valeev