Reputation: 633
I have a private HashMap
and I am using Collections.synchronizedMap()
on it. The API says that it is not really "thread-safe" when the map is iterated. I usually use Map.entrySet()
to iterate maps so I think the map needs a manual synchronization block like the API shows. But from outside I can't synchronize on the map reference because it is private.... I'm wondering if I should provide a getter to the actual map reference (maybe this is not good OOP design), or return a deep copy of the map? (maybe this is slow). I don't know what the best way to go with this kind of situation is. Can somebody give some idea or tell me what is the most typical way to face this situation?
Upvotes: 2
Views: 3780
Reputation: 26029
I would strongly recommend using the ConcurrentHashMap if you really need concurrent access to a HashMap. This is part of the util.concurrent package with Java 5+. It performs much better in a multi-threaded environment than the Synchronized wrappers do.
If you have no control over how the map is created (perhaps it is in a third party library), then you will need to synchronize access when you iterate over it. See the JavaDocs for Collections.synchronizedMap for more info. Here is the sample code included in the API docs.
Map m = Collections.synchronizedMap(new HashMap());
...
Set s = m.keySet(); // Needn't be in synchronized block
...
synchronized (m) { // Synchronizing on m, not s!
Iterator i = s.iterator(); // Must be in synchronized block
while (i.hasNext())
foo(i.next());
}
Upvotes: 3