问题描述
Java并发实践中提到:
The Java Concurrency in Practice mentions that:
- 如何在并行环境中使迭代器弱一致性或故障安全性有帮助,因为
ConcurrentHashMap
的静止状态将被修改。唯一的事情是它不会抛出ConcurrentModificationException
。 - 为什么创建集合时Collection会返回快速失败迭代器故障安全迭代器有利于并发。
- How making the iterator weakly consistent or fail-safe helps in the concurrent environment because still state of the
ConcurrentHashMap
will be modified. The only thing is that it'll not throw theConcurrentModificationException
. - Why fail-fast iterator is returned by the Collections when creating the fail-safe iterator is good for concurrency.
推荐答案
在特定情况下的正确性
请记住,快速失败迭代器会迭代原始集合。
Correctness in your particular case
Please keep in mind that Fail Fast iterator iterates over the original collection.
故障保护(又称弱一致性)迭代器迭代原始集合的副本。因此,对原始集合的任何更改都不会引起注意,这就是它保证缺少 ConcurrentModificationException
s的方式。
In contrast Fail Safe (a.k.a weakly consistent) iterator iterates over a copy of the original collection. Therefore any changes to the original collection go unnoticed, and that's how it guarantees lack of ConcurrentModificationException
s.
回答您的问题:
To answer your questions:
- 使用 Fail Safe 迭代器可以在您不需要时帮助并发不必阻塞整个集合的阅读线程。阅读发生时,可以在下面修改收藏。缺点是读取线程会将集合的状态视为创建迭代器时拍摄的快照。
- 如果上述限制对您的特定用例不利(您的读者应该始终看到集合的相同状态),则必须使用快速失败迭代器并保持对集合的并发访问更加严格。
- Using Fail Safe iterator helps concurrency as you don't have to block on the reading threads on the whole collection. Collection can be modified underneath while the reading happens. The drawback is that the reading thread will see the state of the collection as a snapshot taken at the time when the iterator got created.
- If the above limitation is not good for your particular use case (your readers should always see the same state of the collection) you have to use Fail Fast iterator and keep the concurrent access to the collection controlled tighter.
如您所见,这是用例正确性和速度之间的权衡。
As you can see it's a trade-off between correctness of your use case and speed.
ConcurrentHashMap
( CHM )利用多种技巧来增加访问的并发性。
ConcurrentHashMap
(CHM) exploits multiple tricks in order to increase concurrency of access.
- 首先, CHM 实际上是多个地图的分组;每个
MapEntry
都存储在多个段之一中,每个本身都是可以同时读取的哈希表(read
方法不会阻塞。) - 段的数量是3参数构造函数中的最后一个参数,称为
concurrencyLevel
(默认 16 )。段的数量决定了整个数据中并发写入器的数量。分段之间条目的均等性通过附加的内部哈希算法来确保。 - 每个
HashMapEntry
的值是volatile
从而确保精细的一致性,以便进行有争议的修改和后续读取;每次读取都反映了最近完成的更新 - 迭代器和枚举是 Fail Safe -反映自创建迭代器/枚举以来的某个时刻的状态;这允许同时读取和修改,但会降低一致性。
- Firstly CHM is actually a grouping of multiple maps; each
MapEntry
gets stored in one of the number of segments each itself being a hashtable which can be concurrently read (read
methods do not block). - The number of segments is the last argument in the 3 argument constructor and it is called
concurrencyLevel
(default 16). The number of segments determines the number of concurrent writers across the whole of the data. The equal spread of entries between the segments is ensured by additional internal hashing algorithm. - Each
HashMapEntry
s value isvolatile
thereby ensuring fine grain consistency for contended modifications and subsequent reads; each read reflects the most recently completed update - Iterators and Enumerations are Fail Safe - reflecting the state at some point since the creation of iterator/enumeration; this allows for simultaneous reads and modifications at the cost of reduced consistency.
这篇关于ConcurrentHashMap的弱一致性迭代器的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!