Reputation: 559
Is there any elegant way to make iterating over HashMap.values() threadsafe WITHOUT making a copy of the underlying map?
cheers.
Upvotes: 1
Views: 435
Reputation: 41
The Collections
class in Java contains methods for making various collections synchronized. In your case you should use the synchronizedMap()
method like this
mySyncedMap = Collections.synchronizedMap(myMap);
It is important to note that this method puts a wrapper around the map but the underlying map is still accessible if you keep the reference to it.
The other option is to use the the ConcurrentHashMap
class as it is mentioned in other answers.
Upvotes: 2
Reputation: 5290
I don't really agree with R.Moeller's answer. With a ConcurrentHashMap
you don't get ConcurrentModificationExceptions
while iterating, but it's still not considered threadsafe (see comments).
I would stick with the copy approach, although I wouldn't copy the HashMap.
If you have a HashMap<K,V> myMap
iterate over new ArrayList<V>(myMap.values())
. Makes it easier.
Another approach would be to use a simple counting loop without iterators.
Of course both approaches are not threadsafe so you should include additional checks. Also, concurrently added elements while going through values()
will not be available. I don't think that there is an API solution to that... You'd have to extend ConcurrentHashMap
, creating an iterator which takes deletions and additions into account. But I might be wrong with this part and maybe it's even impossible to do.
Upvotes: 1
Reputation: 3446
1) The only possibility with HashMap is to completely synchronize all access to the map.
2) Use ConcurrentHashMap which is threadsafe (without being fully synchronized internally)
Upvotes: 3