I have a singleton class, that has a map which can be accessed by multiple threads at the same time. Could somebody please check the code below and tell me if its thread safe?
(note: I dont plan to use ConcurrentHashMap, and the printMap method is called only seldom.)
public class MySingleton{
private Map<String,String> cache = Collections.synchronizedMap(
new LinkedHashMap<String,String>());
public String getValue(String key){
return cache.get(key)
}
public void setValue(String key, String value){
cache.put(key, value);
}
public void printMap(){
synchronized(cache){
for(Entry<String,String> entry: cache.entrySet()){
println('key: '+entry.getKey()+', value: ' + value);
}
}
}
}
My test is working… but i am doubting if this code is good enough to be called ‘thread safe’.
points that I considered:
-
The readValue and putValue methods don’t need to have a ‘synchronized’ block since i am using a synchronizedMap
-
printMap should have the synchronized block, since the javadoc for says that we should synchronize the Map instance before each iteration.
http://download.oracle.com/javase/1.5.0/docs/api/java/util/Collections.html#synchronizedMap%28java.util.Map%29
Any help is appreciated.
Yes, that’s okay. The key thing is that while you’re iterating, nothing will be able to modify the map because
cache.putwill end up synchronizing oncacheanyway.Personally I’d rather make that explicit, by using a “normal” hashmap and synchronizing on the same object (whether the map or something else) from all three methods – but what you’ve got should be fine.
(Alternatively, you could use
ConcurrentHashMapto start with. It’s worth at least looking at that.)