Well, the entire hash map (at least conceptually, the actual implementation is a bit more complicated) is an array of linked lists. A safe ( not thread safe ) iterator can be implemented very trivially by going through linked lists one by one, starting from the first node to the last. Something like this will work:
public boolean hasNext() { if(next != null) return true; currentNode = currentNode == null ? null : currentNode.next; // volatile while(currentNode == null && ++currentIndex < buckets.length) // assume the length is fixed for simplicity currentNode = buckets[currentIndex].head; // also volatile if(currentNode != null) next = currentNode.data; return currentNode != null; } public Object next { if(!hasNext()) throw new NoSuchElementException(); Object result = next; next = null; return result; }
This is not very specific to ConcurrentHashMap , they could implement it this way for regular cards, but they didn’t decide. What for? Well, because a “regular” card is not thread safe, so modifying it at the same time is not a good idea, so if this happens, it is most likely an error rather than an intentional occurrence, so it’s better to “quickly fail” as soon as the situation will be detected, but will not ignore it and continue, risking a potential subtle and difficult way to diagnose inconsistencies in the future.
If you ask me if I agree with this last expression, the answer is “no” :) But, apparently, there were enough people among java designers who at least came back when this decision was made.
source share