ConcurrentHashMap putIfAbsent: атомарность, за которой следует вызов get ()

Я хотел обсудить конкретное использование параллельной карты, чтобы проверить мою логику ...

Если бы я использовал ConcurrentHashMap , Я могу выполнить знакомое

private final ConcurrentHashMap<K, V> map = new ConcurrentHashMap<K, V>();

public V getExampleOne(K key) {
    map.putIfAbsent(key, new Object());
    return map.get(key);
}

, но я понимаю, что существует условие гонки , при котором, если я удалю элемент с карты между putIfAbsent и get ] , приведенный выше метод вернет то, чего больше нет в коллекции. Это может быть хорошо, а может и нет, но давайте предположим, что для моего варианта использования это не нормально.

Я действительно хотел бы, чтобы все это было атомарным. Итак,

public V getExampleTwo(K key) {
    return map.putIfAbsent(key, new Object());
}

, но по мере расширения до

if (!map.containsKey(key))
   return map.put(key, value);     [1]
return map.get(key);

, который для строки [1] вернет null для первого использования (т.е. map.put вернет предыдущее значение, который при первом использовании равен null ).

Я не могу вернуть null в этом случае

Что оставляет мне что-то вроде:

public V getExampleThree(K key) {
    Object object = new Object();
    V value = locks.putIfAbsent(key, object);
    if (value == null)
        return object;
    return value;
}

Итак, наконец, мой вопрос; как приведенные выше примеры отличаются семантикой ?. Обеспечивает ли getExampleThree атомарность, как getExampleTwo , но правильно ли избегает нулевого возврата? Есть ли другие проблемы с getExampleThree ?

Я немного надеялся обсуждения выбора.Я понимаю, что могу использовать не ConcurrentHashMap и синхронизировать клиентов, вызывая мой метод get и метод, который нужно удалить с карты, но это, похоже, нарушает цель (неблокирующий характер) ConcurrentHashMap. Неужели это единственный мой выбор, чтобы данные были точными ?

Думаю, это небольшая часть того, почему вы выбрали ConcurrentHashMap; что он виден / актуален / точен в момент, когда вы с ним взаимодействуете, но могут возникнуть последствия, если старые данные будут проблемой ...

5
задан Toby 3 September 2014 в 07:33
поделиться