Двойная проверка блокировки с обычным HashMap

Вернуться к параллелизму. К настоящему времени ясно, что дляdouble checked locking для работы переменная должна быть объявлена ​​какvolatile, Но что делать, если двойная проверка блокировки используется, как показано ниже.

class Test<A, B> {

    private final Map<A, B> map = new HashMap<>();

    public B fetch(A key, Function<A, B> loader) {
        B value = map.get(key);
        if (value == null) {
            synchronized (this) {
                value = map.get(key);
                if (value == null) {
                    value = loader.apply(key);
                    map.put(key, value);
                }
            }
        }
        return value;
    }

}

Почему это действительно должно бытьConcurrentHashMap и не обычныйHashMap? Все изменения карты выполняются в пределахsynchronized блок и код не использует итераторы, так что технически не должно быть проблем "одновременного изменения".

Пожалуйста, избегайте использованияputIfAbsent/computeIfAbsent как я спрашиваю оконцепция а не использование API :), если использование этого API не способствуетHashMap противConcurrentHashMap предмет.

Обновление 2016-12-30

На этот вопрос ответил комментарий ниже от Holger "HashMap.get не изменяет структуру, но ваш вызовput делает. Так как есть вызовget вне синхронизированного блока, он может видеть неполное состояниеput операция происходит одновременно. "Спасибо!

Ответы на вопрос(1)

Ваш ответ на вопрос