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.
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.
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.
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.
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.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With