[英]Is KeySet iterator of ConcurrentHashMap is threadsafe?
我只是想探索ThreadSafe是什么意思?
以下是我的理解:
它看起来像我; 允许多个线程同时访问集合; 这与其同步无关。 例如,没有synchronized关键字的任何方法; 是线程安全的,意味着多个线程可以访问它。
开发人员可以选择在此方法上维护更多逻辑(同步),以便在多线程访问数据时保持数据完整性。 这与线程安全是分开的。
如果我的上述陈述是假的; 只需阅读以下JAVA DOC中的`ConcurrentHashMap:
keySet:视图的迭代器是一个“弱一致”的迭代器,它永远不会抛出ConcurrentModificationException,并保证遍历构造迭代器时存在的元素,并且可能(但不保证)反映构造之后的任何修改。
上面的语句说keySet迭代器不能保证数据的完整性; 而多线程正在修改集合。
你能回答我吗,* ConcurrentHashMap的KeySet迭代器是线程安全的吗?
我对线程安全的理解是正确的吗?
keySet:视图的迭代器是一个“弱一致”的迭代器,它永远不会抛出ConcurrentModificationException,并保证遍历构造迭代器时存在的元素,并且可能(但不保证)反映构造之后的任何修改
这本身就解释了, ConcurrentHashMap的KeySet迭代器是线程安全的。
java.util.concurrent
包背后的一般思想是提供一组数据结构,这些数据结构提供了线程安全的访问而没有很强的一致性。 这样,这些对象实现了更高的并发性,然后正确锁定了对象
线程安全意味着,即使没有任何明确的同步,您也不会破坏对象。 在HashTable
和HashMap
一些方法是多线程访问的潜在问题,例如remove
方法,它首先检查元素是否存在,然后将其删除。 这些方法在ConcurrentHashMap
中实现为原子操作,因此您不必担心会丢失一些数据。
但是,这并不意味着每个操作都会自动锁定此类。 诸如putAll
和迭代器之类的高级操作不同步。 该课程不具备强大的一致性。 保证操作的顺序和时间不会破坏对象,但不能保证生成准确的结果。
例如,如果您通过调用putAll
同时打印对象,则可能会看到部分填充的输出。 与新插入同时使用迭代器也可能无法反映所引用的所有插入。
这与线程安全不同。 即使结果可能会让您大吃一惊,但您可以放心,不会丢失或意外覆盖任何内容,可以毫无问题地添加和删除元素。 如果此行为足以满足您的要求,建议您使用java.util.concurrent
类。 如果需要更多一致性,则需要使用java.util
synchronized类或自己使用同步。
根据您的定义, ConcurrentHashMap.keySet()
返回的Set
是线程安全的。
但是,正如您所包含的引用中所指出的,它可能以非常奇怪的方式起作用。
Set
,条目可以随机出现和/或消失。 即如果你在同一个对象上调用contains
两次,则两个结果可能不同。 Iterable
您可以在两个不同的线程中开始其底层对象的两次迭代,并发现两次迭代枚举不同的条目。 contains
和迭代可能也不匹配。 但是,如果您在保留Set
时以某种方式锁定底层Map
,则不会发生此活动,但需要这样做并不意味着该结构不是线程安全的。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.