有 Java 编程相关的问题?

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

java ConcurrentHashMap返回一个弱一致迭代器,我们为什么要使用它呢?

我正在读《实践中的Java》。第85页第5.2.1节讨论了ConcurrentHashMap及其优点。然而,书中有一部分声称

the iterators returned by ConcurrentHashMap is weakly consistent. This means that this iterator can tolerate concurrent modification, traverses elements as they existed when iterator was constructed, and may (but not guaranteed to) reflect modifications to the collection after the construction of the iterator.

从我的理解来看,并发程序中的整个同步点是允许线程以一致的方式访问共享资源,而ConcurrentHashMap并不能真正实现这一点。那为什么要用它呢


共 (3) 个答案

  1. # 1 楼答案

    关键是在不需要同步时避免同步。如果您不介意在某些情况下看到新元素而在其他情况下看不到新元素,那么使用ConcurrentHashMap的迭代器可能比要便宜得多,或者在迭代时阻止其他线程添加项,或者在创建迭代器时拍摄一致的快照

    因此,是的,当您需要同步和一致迭代器时,您将需要一个替代方法—但当您不需要时,您可以利用ConcurrentHashMap提供的更高效的迭代器

  2. # 2 楼答案

    一切都取决于你需要多强的一致性。如果您需要强一比互斥或其他操作子集将提供您所需要的

    然而,有时您需要更弱的要求,但例如,您需要说无锁属性,因为您需要保证吞吐量。另一方面,您可能根本不需要迭代器,或者对迭代器的限制要弱得多

    因此,如果您所需要的只是跨线程共享映射ConcurrentHashMap(比如剧院中的地点到预定的人),那么它将提供您所需要的—如果您有许多工作线程,并且避免了互斥同步,那么它可能会快得多。另一方面,速度是有代价的——迭代器提供的视图在创建时不需要对应于集合状态,并且可能会丢失一些在后置词中创建的元素(通常在多处理器系统中happens-before关系很复杂)

    编辑:正如约翰·卫斯理亲王指出的那样,我在看和写的时候想到了ConcurrentSkipListMapConcurrentHashMap。除了关于无锁的部分(以及来自它的所有内容,如保证吞吐量等),大多数要点仍然有效

  3. # 3 楼答案

    ConcurrentHashMap根据约定应该是线程安全的。但是,它不应该在线程间保持一致

    当您在ConcurrentHashMap上迭代时,迭代器会在您请求时获取哈希映射的副本(并且副本是以线程安全的方式创建的),然后您对该副本进行迭代。是的,没有任何东西可以保证当您在该副本上迭代时,某些映射条目不会被删除。但是以这种方式删除的映射项仍然存在于迭代器中