Let's say I have the following (assume restricted to java 1.4 so no generics) :
public class CacheManager {
static HashMap states;
static boolean statesLoaded;
public static String getState(String abbrev) {
if(!statesLoaded) {
loadStates();
}
return (String) states.get(abbrev);
}
private static void loadStates() {
//JDBC stuff to load the data
statesLoaded = true;
}
}
In a high-load multi-thread environment like a web app server, this could theoretically have problems if > 1 thread tries to get and load the cache at the same time. (Further assuming there's no startup code on the web app to initialize the cache)
Is simply using Collections.synchronizedMap sufficient to fix this? Does the returned synchronizedMap have performance issues when doing get(), if a lot of threads are accessing it?
Or would it be better to have a non-synchronized HashMap, and instead synchronize on the load method or boolean variable? I would think that if you synchronized either of those, you might end up locking the class.
For instance, if the load method was synchronized, what if 2 threads enter the getStates() method at the same time, and both see that statesLoaded is false. The first one gets a lock on the method, loads the cache and sets statesLoaded to true. Unfortunately, the 2nd thread has already evaluated that statesLoaded was false, and proceeds to the load method once the lock is free. Won't it go ahead and load the cache again?