Приговор вынесен. Я рассчитал 3 разных решения с точностью до наносекунды, так как после всего первоначального вопроса был о производительности:
Полная синхронизация функции на обычном HashMap :
synchronized (map) {
Object result = map.get(key);
if (result == null) {
result = new Object();
map.put(key, result);
}
return result;
}
первый вызов: 15 000 наносекунд, последующие вызовы: 700 наносекунд
Использование двойной проверки блокировки с ConcurrentHashMap :
if (!map.containsKey(key)) {
synchronized (map) {
if (!map.containsKey(key)) {
map.put(key, new Object());
}
}
}
return map.get(key);
первый вызов: 15 000 наносекунд, последующие вызовы: 1500 наносекунд
Другой вариант двойной проверки ConcurrentHashMap :
Object result = map.get(key);
if (result == null) {
synchronized (map) {
if (!map.containsKey(key)) {
result = new Object();
map.put(key, result);
} else {
result = map.get(key);
}
}
}
return result;
первый вызов: 15 000 наносекунд, последующие вызовы: 1000 наносекунд
Вы можете видеть, что самая большая стоимость была при первом вызове, но была аналогичной для всех 3. Последующие вызовы были самыми быстрыми в обычном HashMap с синхронизацией методов, как предложено user237815, но только с 300 NANO-секундами.И в конце концов, мы говорим здесь о NANO секундах, что означает МИЛЛИАРД секунды.