有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java是ConcurrentHashMap的密钥集迭代器是线程安全的吗?

我只是想探索什么是线程安全

以下是我的理解:

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

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

如果我的上述陈述是错误的;只需阅读以下JAVA文档中的“ConcurrentHashMap”:

keySet: The view's iterator is a "weakly consistent" iterator that will never throw ConcurrentModificationException, and guarantees to traverse elements as they existed upon construction of the iterator, and may (but is not guaranteed to) reflect any modifications subsequent to construction.

上述声明表示,密钥集迭代器将不能保证数据的完整性;当多线程正在修改集合时

你能回答我吗,*ConcurrentHashMap的密钥集迭代器是线程安全的吗

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


共 (3) 个答案

  1. # 1 楼答案

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

    然而,正如你在引用中所指出的,它的行为可能非常奇怪

    1. 作为Set,条目可能会随机出现和/或消失。也就是说,如果在同一个对象上调用contains两次,两个结果可能会不同
    2. 作为一个Iterable,您可以在两个不同的线程中开始其底层对象的两次迭代,并发现这两次迭代枚举了不同的条目
    3. 此外,MRE、contains和迭代也可能不匹配

    但是,如果您在控制Set的同时以某种方式锁定了底层Map的修改,则不会发生此活动,但这样做并不意味着该结构不是线程安全的

  2. # 2 楼答案

    keySet: The view's iterator is a "weakly consistent" iterator that will never throw ConcurrentModificationException, and guarantees to traverse elements as they existed upon construction of the iterator, and may (but is not guaranteed to) reflect any modifications subsequent to construction

    这本身就解释了ConcurrentHashMap的键集迭代器是线程安全的

  3. # 3 楼答案

    java.util.concurrent包背后的总体思想是提供一组数据结构,这些数据结构提供线程安全的访问,而不具有很强的一致性。通过这种方式,这些对象实现了比正确锁定的对象更高的并发性

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

    但是,这并不意味着每次操作都会自动锁定此类。诸如putAll和迭代器之类的高级操作不同步。该类没有提供很强的一致性。操作的顺序和时间保证不会损坏对象,但不能保证生成准确的结果

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

    这与线程安全不同。尽管结果可能会让您感到惊讶,但您可以放心,不会丢失或意外覆盖任何内容,元素会毫无问题地添加到对象中或从对象中删除。如果这种行为足以满足您的需求,建议您使用java.util.concurrent类。如果需要更高的一致性,那么需要使用java.util中的同步类,或者自己使用同步