简体   繁体   中英

Concurrenthashmap Iterator data structure

I needed to ask on the below aspects of the ConcurrentHashMap,as I am unable to figure it out from the source code.
(Please note that I am not asking about the behaviour ,which is well understood. Its about the mechanism the iterator adopts to display the behaviour)

"The iterator is guaranteed to reflect the state of the map at the time of it's creation."

1.Does this mean that the iterator gets its own copy of the backing map? Why else would volatile reads not give true state of 'value' ,even after creation of the iterator? (exact location of the code will be appreciated)

2.How does the non-blocking read and iteration manage to behave consistently,even when a segment is undergoing re-hashing?

As mentioned in the comments, I'm not convinced that ConcurrentHashMap behaviour is "well understood". The assertion made in your unattributed quote is not true for ConcurrentHashMap.

The iterator for a ConcurrentHashMap is weakly consistent ... the javadoc states:

Iterators, Spliterators and Enumerations return elements reflecting the state of the hash table at some point at or since the creation of the iterator/enumeration.

In light of this,

The short answer to your question 1 is: no, it does not get its own copy of the map

The short answer to your question 2 is: that it doesn't "behave consistently"


Here are some other pertinent quotes from the javadocs that help explain the implementation:

The basic strategy is to subdivide the table among Segments, each of which itself is a concurrently readable hash table...

Segments maintain a table of entry lists that are always kept in a consistent state, so can be read (via volatile reads of segments and tables) without locking. This requires replicating nodes when necessary during table resizing, so the old lists can be traversed by readers still using old version of table.

Node replication occurs for each Segment in its rehash method. The javadocs for the Segment.rehash() method explain the functionality:

Reclassify nodes in each list to new table. Because we are using power-of-two expansion, the elements from each bin must either stay at same index, or move with a power of two offset. We eliminate unnecessary node creation by catching cases where old nodes can be reused because their next fields won't change. Statistically, at the default threshold, only about one-sixth of them need cloning when a table doubles. The nodes they replace will be garbage collectable as soon as they are no longer referenced by any reader thread that may be in the midst of concurrently traversing table. Entry accesses use plain array indexing because they are followed by volatile table write.

Please see Richard Burnison's excellent article for a good overview description of the implementation details of ConcurrentHashMap for jdk 7.


For further information:

Javadocs for ConcurrentHashMap jdk8

Source code for ConcurrentHashMap (openjdk-7)

ConcurrentHashMap returns a weakly consistent iterator, why should we use it anyhow?

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM