繁体   English   中英

ConcurrentHashMap的KeySet迭代器是线程安全的吗?

[英]Is KeySet iterator of ConcurrentHashMap is threadsafe?

我只是想探索ThreadSafe是什么意思?

以下是我的理解:

它看起来像我; 允许多个线程同时访问集合; 这与其同步无关。 例如,没有synchronized关键字的任何方法; 是线程安全的,意味着多个线程可以访问它。

开发人员可以选择在此方法上维护更多逻辑(同步),以便在多线程访问数据时保持数据完整性。 这与线程安全是分开的。

如果我的上述陈述是假的; 只需阅读以下JAVA DOC中的`ConcurrentHashMap:

keySet:视图的迭代器是一个“弱一致”的迭代器,它永远不会抛出ConcurrentModificationException,并保证遍历构造迭代器时存在的元素,并且可能(但不保证)反映构造之后的任何修改。

上面的语句说keySet迭代器不能保证数据的完整性; 而多线程正在修改集合。

你能回答我吗,* ConcurrentHashMap的KeySet迭代器是线程安全的吗?

我对线程安全的理解是正确的吗?

keySet:视图的迭代器是一个“弱一致”的迭代器,它永远不会抛出ConcurrentModificationException,并保证遍历构造迭代器时存在的元素,并且可能(但不保证)反映构造之后的任何修改

这本身就解释了, ConcurrentHashMap的KeySet迭代器是线程安全的。

java.util.concurrent包背后的一般思想是提供一组数据结构,这些数据结构提供了线程安全的访问而没有很强的一致性。 这样,这些对象实现了更高的并发性,然后正确锁定了对象

线程安全意味着,即使没有任何明确的同步,您也不会破坏对象。 HashTableHashMap一些方法是多线程访问的潜在问题,例如remove方法,它首先检查元素是否存在,然后将其删除。 这些方法在ConcurrentHashMap中实现为原子操作,因此您不必担心会丢失一些数据。

但是,这并不意味着每个操作都会自动锁定此类。 诸如putAll和迭代器之类的高级操作不同步。 该课程不具备强大的一致性。 保证操作的顺序和时间不会破坏对象,但不能保证生成准确的结果。

例如,如果您通过调用putAll同时打印对象,则可能会看到部分填充的输出。 与新插入同时使用迭代器也可能无法反映所引用的所有插入。

这与线程安全不同。 即使结果可能会让您大吃一惊,但您可以放心,不会丢失或意外覆盖任何内容,可以毫无问题地添加和删除元素。 如果此行为足以满足您的要求,建议您使用java.util.concurrent类。 如果需要更多一致性,则需要使用java.util synchronized类或自己使用同步。

根据您的定义, ConcurrentHashMap.keySet()返回的Set 线程安全的。

但是,正如您所包含的引用中所指出的,它可能以非常奇怪的方式起作用。

  1. 作为Set ,条目可以随机出现和/或消失。 即如果你在同一个对象上调用contains两次,则两个结果可能不同。
  2. 作为Iterable您可以在两个不同的线程中开始其底层对象的两次迭代,并发现两次迭代枚举不同的条目。
  3. 进一步, contains和迭代可能也不匹配。

但是,如果您在保留Set时以某种方式锁定底层Map ,则不会发生此活动,但需要这样做并不意味着该结构不是线程安全的。

暂无
暂无

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

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