I’m writing an analogue of DatabaseConfiguration class which reads configuration from database and I need some advice regards synchronization.
For example,
public class MyDBConfiguration{
private Connection cn;
private String table_name;
private Map<String, String> key_values = new HashMap<String,String>();
public MyDBConfiguration (Connection cn, String table_name) {
this.cn = cn;
this.table_name = table_name;
reloadConfig();
}
public String getProperty(String key){
return this.key_values.get(key);
}
public void reloadConfig() {
Map<String, String> tmp_map = new HashMap<String,String> ();
// read data from database
synchronized(this.key_values)
{
this.key_values = tmp_map;
}
}
}
So I have a couple questions.
1. Assuming properties are read only , do I have use synchronize in getProperty ?
2. Does it make sense to do this.key_values = Collections.synchronizedMap(tmp_map) in reloadConfig?
Thank you.
Assuming that key_values will not be
putto afterreloadConfigyou will need to synchronize access to both reads and writes of the map. You are violating this by only synchronizing on the assignment. You can solve this by removing the synchronized block and assigning the key_values asvolatile.Since the HashMap is effectively read only I wouldn’t assign
Collections.synchronizedMapratherCollections.unmodifiableMap(this wouldn’t effect the Map itself, just prohibit from accidentalputs from someone else possible using this class).Note: Also, you should never synchronize a field that will change. The results are very unpredictable.
Edit: In regards to the other answers. It is highly suggested that all shared mutable data must be synchronized as the effects are non-deterministic. The
key_valuesfield is a shared mutable field and assignments to it must be synchronized.Edit: And to clear up any confusion with Bruno Reis. The
volatilefield would be legal if you still fill thetmp_mapand after its finished being filled assign it tothis.key_valuesit would look like:You still need the same style or else as Bruno Reis noted it would not be thread-safe.