简体   繁体   English

如何限制Stream顺序运行,并防止其并行运行?

[英]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. 我的确在BaseStream类上找到了BaseStream sequential()方法,但这似乎并不能阻止用户随后调用parallel()来获取并行流。

Parallel stream calls trySplit() method of your spliterator to split your task to the several parts. 并行流调用trySplit()方法,将您的任务拆分为几个部分。 It's absolutely legit to return null from trySplit() saying that "I refuse to split". trySplit()返回null表示“我拒绝拆分”是绝对合法的 In this case the stream created from your spliterator will be executed sequentially even if .parallel() was explicitly called. 在这种情况下,即使显式调用了.parallel()也将按顺序执行从您的分隔器创建的流。

However in general you may provide at least a limited parallelism extending the AbstractSpliterator class. 但是,通常,您可以提供至少一个有限的并行度来扩展AbstractSpliterator类。 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. 它提供了默认的trySplit()实现,该实现读取一些调用tryAdvance()方法的输入元素,将它们存储到数组中并返回该数组上的分隔符,因此该部分可以单独处理,并且完全独立于分隔符。 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. 最后请注意,在大多数简单情况下,Spliterator实现都不应该是线程安全的。 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. 如果您提供自己有效的trySplit()实现,则可以确保将以完全独立的方式处理原始拆分器和新创建的拆分器。 So if you don't modify the shared state in prefix and suffix spliterator after splitting, you should not care about thread-safety. 因此,如果在拆分后不修改前缀和后缀拆分器中的共享状态,则不必担心线程安全。

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: 有一种方法可以检查线程,是否可以通过API在服务器端发送线程ID,并在客户端通过API接收线程ID:

Thread.currentThread().getId()

And compare it with your Thread ID when you receive it. 并将其与您的线程ID进行比较。 Throw an Exception with a clear error message "Not Thread-Safe!" 引发Exception并显示明确的错误消息“不是线程安全的!” when they are different. 当它们不同时。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM