Reputation: 113
ConcurrentHashMap is thread safe. So if am adding any values to map at the time of iterating, it should not consider them. Below is my code:
public class Test {
public static void main(String[] args) {
ConcurrentHashMap<String, Integer> map = new ConcurrentHashMap<String, Integer>();
map.put("ONE", 1);
map.put("TWO", 2);
Iterator<String> it = map.keySet().iterator();
while (it.hasNext()) {
String key = (String) it.next();
System.out.println(key + " : " + map.get(key));
map.put("9", 10); // This should not be reflected in the Iterator
map.put("5", 10); // This should not be reflected in the Iterator
}
}
}
TWO : 2
ONE : 1
9 : 10
My question is why iterator considering map.put("9", 10);
Upvotes: 1
Views: 119
Reputation: 3964
ConcurrentHashMap is thread safe, but this is a different scenario.
With a List you can use ListIterator with ListIterator.Add which is designed for that.
With HashMap I see two solutions:
Convert to List and then back to HashMap
Use an additional HashMap for new elements, after the loop ends, use another loop to add all new elements (not quite elegant, but works!).
With Java 8 you may consider using lambda-expressions to simplify the code.
Upvotes: 1
Reputation: 719229
ConcurrentHashMap is thread safe. So if am adding any values to map at the time of iterating, it should not consider them.
That is not correct. This is what the javadoc says:
"Similarly, 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."
Note the "or since"!
And it also says that the iterators are "weakly consistent" which means that:
"they are guaranteed to traverse elements as they existed upon construction exactly once, and may (but are not guaranteed to) reflect any modifications subsequent to construction."
In short, you are expecting properties of the iterators that the javadocs plainly do not say that they have.
Upvotes: 3