Java ConcurrentHashMap的键集迭代器是线程安全的吗?

Java ConcurrentHashMap的键集迭代器是线程安全的吗?,java,multithreading,Java,Multithreading,我只是想探索什么是线程安全? 以下是我的理解: 对我来说是这样的;允许多个线程同时访问一个集合;这与它的同步无关。例如,任何没有同步关键字的方法;是线程安全的,意味着多个线程可以访问它 开发人员可以选择在这个方法上维护更多的逻辑(同步),以在多线程访问数据时保持数据完整性。这是独立于线程安全的 如果我的上述陈述是错误的;只需阅读以下JAVA文档中的“ConcurrentHashMap”: keySet:视图的迭代器是一个“弱一致”迭代器,它永远不会抛出 ConcurrentModificatio

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

以下是我的理解:

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

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

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

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

上面的语句表示密钥集迭代器不能保证数据的完整性;当多线程正在修改集合时

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

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

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


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

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

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

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

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


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

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

然而,正如您在引用中所指出的,它可能以非常奇怪的方式运行

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

  • 但是,这种活动不会发生,如果您在掌握
    集合的同时,以某种方式锁定了基础
    映射
    ,但这样做并不意味着结构不是线程安全的。

    您的问题本身就有答案。正如javadoc所说,这是非常清楚的,没有任何答案可以更好或更清晰地解释它。您到底不明白什么?ConcurrentHashMap keySet()是线程安全的,因此可能不需要同步或复制。“迭代器永远不会抛出ConcurrentModificationException,并保证在构造迭代器时遍历元素”——这就足够实现“线程安全”。问题是,你到底把什么定义为“线程安全”…@afk5min引用的是你对线程安全的定义吗??因此,这意味着线程安全无法确保对集合进行什么修改。。只允许多个线程能够遍历元素..?那么你的意思是threadsafe在访问它时超出了数据完整性/一致性..?所以我可以使用迭代器看到很多不一致性;那么为什么它被称为线程安全。。。?或者是线程安全性不符合数据一致性?@KanagaveluSugumar-线程安全意味着通过多个线程访问它不会中断或崩溃。如果你在意的话,它可能会给你带来不一致的结果——你必须保护自己。开发人员可以选择在这个方法上维护更多的逻辑(同步),以在多线程访问数据时保持数据完整性。Ohhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh。。?它是。。?所以我的理解是正确的。。?这个问题的最佳答案是错误的,是吗?@KanagaveluSugumar-在我看来,线程安全意味着如果在写入时不使用
    synchronized
    ,结构可能会损坏。这并不是一个好主意