ConcurrentHashMap的弱一致性迭代器

Man*_*ish 1 java concurrency concurrenthashmap

实践中的Java并发提到:

由返回的迭代器ConcurrentHashMap比快速失败弱一致。弱一致性迭代器可以容忍并发修改,遍历在构造迭代器时存在的元素,并且可以(但不能保证)在构造迭代器后将对集合的修改反映出来。

  1. 在并行环境中,如何使迭代器保持弱​​一致性或故障安全性是有帮助的,因为ConcurrentHashMap将修改静态状态。唯一的事情是它不会抛出ConcurrentModificationException
  2. 为什么创建故障安全迭代器时Collections返回故障快速迭代器有利于并发。

dig*_*ise 5

在特定情况下的正确性

请记住,Fail Fast迭代器会迭代原始集合。

相反,Fail Safe(又称弱一致性)迭代器遍历原始集合的副本。因此,对原始集合的任何更改都不会引起注意,这就是它保证缺少ConcurrentModificationExceptions的方式。


要回答您的问题:

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

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

并发哈希图

ConcurrentHashMapCHM)利用多种技巧来增加访问的并发性。

  • 首先,CHM实际上是多个地图的分组;每个MapEntry都存储在多个之一中,每个本身都是可以同时读取的哈希表(read方法不会阻塞)。
  • 数是3参数构造函数中的最后一个参数,它被称为concurrencyLevel(默认值为16)。段的数量决定了整个数据中的并发写入器的数量。片段之间条目的均等分布是通过附加的内部哈希算法来确保的。
  • 因此,每个HashMapEntrys值可volatile确保在进行有争议的修改和后续读取时具有良好的颗粒一致性;每次读取均反映最近完成的更新
  • 迭代器和枚举是故障安全的 -反映自创建迭代器/枚举以来的某个时刻的状态;这允许同时读取和修改,但以降低一致性为代价。