问题
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.
回答1:
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.
回答2:
Streams are synchronous by default, so the question is kinda irrelevant if you document your library correctly. It's the user's responsibility to make sure the library they are using is Thread-Safe. Just make obvious yours is not.
There is a way to check the Thread if you can send the Thread ID on the server side and receive it on the client side through an API:
Thread.currentThread().getId()
And compare it with your Thread ID when you receive it. Throw an Exception
with a clear error message "Not Thread-Safe!" when they are different.
来源:https://stackoverflow.com/questions/33835683/how-to-restrict-a-stream-to-run-sequentially-and-prevent-it-from-running-in-par