Spliterator:线程安全与否?

时间:2017-08-02 10:18:22

标签: java-8 iterator thread-safety java-stream spliterator

我正在研究Spliterator的文档,根据它,Spliterator不是线程安全的:

  

尽管它们在并行算法中具有明显的实用性,但预计分裂器不是线程安全的。相反,使用分裂器的并行算法的实现应确保分裂器一次仅由一个线程使用。这通常很容易通过串行线程限制来实现,这通常是通过递归分解工作的典型并行算法的自然结果。

但是,在其进一步的文件中,陈述了对上述陈述的矛盾陈述:

  

源的结构干扰可以通过以下方式进行管理(大致降低合意性的顺序):

     

源管理并发修改。   例如,java.util.concurrent.ConcurrentHashMap的键集是并发源。从源创建的Spliterator报告CONCURRENT的特征。

那么这是否意味着从线程安全的集合生成的Spliterator是线程安全的?是不是?

1 个答案:

答案 0 :(得分:7)

不,报告Spliterator特征的CONCURRENT将具有线程安全的,这意味着即使源同时被修改,它也可以安全地迭代它。但是Spliterator本身可能仍然具有不能同时操纵的状态。

请注意,您的引用源于对“源的结构干扰如何管理”的描述,而不是关于分裂者的行为。

documentation of the CONCURRENT characteristic itself

也提供了此功能
  

特征值,表示可以在没有外部同步的情况下由多个线程安全地同时修改元素源(允许添加,替换和/或删除)。如果是这样,Spliterator应该有关于遍历期间修改影响的文档化政策。

别无其他。

因此这些特征的后果令人惊讶地小。报告SpliteratorCONCURRENT IMMUTABLE永远不会抛出ConcurrentModificationException,这就是全部。在所有其他方面,Stream API无法识别这些特征之间的差异,因为Stream API从不执行任何源操作,事实上,它实际上并不知道源(其他而不是间接地通过Spliterator),所以它不能进行这样的操作,也不能检测是否发生了并发修改。