java - ConcurrentHashMap 的弱一致迭代器

标签 java concurrency concurrenthashmap

《Java 并发实践》提到:

The iterator returned by the ConcurrentHashMap are weakly consistent than fail-fast. A weakly consistent iterator can tolerate the concurrent modifications, traverses elements as they existed when the iterator was constructed, and may (but is not guaranteed to) reflect modifications to the collection after the construction of the iterator.

  1. 如何使迭代器弱一致或故障安全在并发环境中有所帮助,因为 ConcurrentHashMap 的状态仍然会被修改。唯一的问题是它不会抛出 ConcurrentModificationException
  2. 为什么在创建故障安全迭代器时集合返回故障快速迭代器有利于并发。

最佳答案

您的具体情况的正确性

请记住,快速失败迭代器会迭代原始集合。

相反,故障安全(又名弱一致)迭代器迭代原始集合的副本。因此,对原始集合的任何更改都不会被注意到,这就是它保证不存在 ConcurrentModificationException 的方式。


回答您的问题:

  1. 使用故障安全迭代器有助于并发,因为您不必阻塞整个集合的读取线程。阅读时可以在下面修改集合。缺点是读取线程会将集合的状态视为创建迭代器时拍摄的快照。
  2. 如果上述限制不适合您的特定用例(您的读者应该始终看到集合的相同状态),您必须使用快速失败迭代器并保持对集合的并发访问控制得更严密。

正如您所看到的,这是用例的正确性和速度之间的权衡。

并发 HashMap

ConcurrentHashMap (CHM) 利用多种技巧来提高访问的并发性。

  • 首先CHM实际上是多个 map 的分组;每个MapEntry都存储在多个之一中,每个段本身都是一个可以同时读取的哈希表(read方法不会阻塞)。
  • 的数量是 3 参数构造函数中的最后一个参数,称为concurrencyLevel(默认16)。段的数量决定了整个数据中并发写入的数量。额外的内部哈希算法确保了段之间条目的均匀分布。
  • 每个 HashMapEntry 的值都是 volatile ,从而确保争用修改和后续读取的细粒度一致性;每次读取都会反射(reflect)最近完成的更新
  • 迭代器和枚举是故障安全 - 反射(reflect)自迭代器/枚举创建以来某个时刻的状态;这允许同时读取和修改,但代价是降低了一致性。

关于java - ConcurrentHashMap 的弱一致迭代器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36079344/

相关文章:

java - spring data jpa复合键重复键记录插入导致更新

java - 如何使用 rJava 访问枚举?

multithreading - 如何在Websocket中使用超时,同时又不影响应用程序安全性?

java - Java 标准输入中的空值

java - 锁定与直接更新

java - ReentrantLock 替代 CountdownLatch

java - 对 java ConcurrentHashMap 中的值进行排序

dictionary - golang struct concurrent read and write without Lock 也运行ok?

java - java 流会以一致的方式对 ConcurrentHashMap 的值求和吗?

java - 我怎样才能用给定的实例变量创建一个可调整大小的条,并为其设置两种不同的颜色,红色代表 (a) 绿色代表 (b)?