Допустим, у меня есть следующее (предположим, ограничено Java 1.4, поэтому нет универсальных):
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;
}
}
В многопоточной среде с высокой нагрузкой, такой как сервер веб-приложений, теоретически могут возникнуть проблемы, если> 1 поток попытается получить и загрузить кэш одновременно. (Далее, при условии, что в веб-приложении нет кода запуска для инициализации кэша)
Достаточно ли просто использовать Collections.synchronizedMap, чтобы это исправить? Есть ли у возвращенного synchronizedMap проблемы с производительностью при выполнении get (), если к нему обращается множество потоков?
Или было бы лучше иметь несинхронизированный HashMap и вместо этого синхронизировать метод загрузки или логическую переменную? Я думаю, что если вы синхронизируете один из них, вы можете заблокировать класс.
Например, если метод загрузки был синхронизирован, что, если 2 потока одновременно вводят метод getStates (), и оба видят, что statesLoaded имеет значение false. Первый получает блокировку метода, загружает кэш и устанавливает для StatesLoaded значение true. К сожалению, 2-й поток уже оценил, что statesLoaded был ложным, и переходит к методу загрузки, как только блокировка освобождается. Разве это не пойдет и снова загрузите кеш?