Является ли метод, содержащий содержимое параллельной коллекции бесполезным? - PullRequest
3 голосов
/ 30 января 2012
if(concurrentHashMap.containKey(key))
{
    // oops, v has been removed in another thread right after current thread 
    // complete containKey calling
    Value v = concurrentHashMap.get(key); 
    // do something on v                  // null pointer exception
}

Кажется, что подобный метод одновременной коллекции бесполезен, чтобы решить вышеуказанную проблему:

Vaule v = concurrentHashMap.get(key);
if(v != null)
{
    // ok, hold v's reference
    // do something on v
}

Я прав?

Ответы [ 2 ]

5 голосов
/ 30 января 2012

Это не бесполезно. Представьте себе случай, когда ничего не нужно делать с результатом get. В этом случае и containsKey, и get имеют (и страдают) одинаковые проблемы.

Как указывает Voo в комментарии, код часто может быть записан в виде putIfAbsent (который предназначен для представления атомарной операции большего размера).

Это просто не (как он не может сам по себе) не создает больший атомный контекст . То есть ничто не позволяет другим потокам делать что-либо с concurrentHashMap между containsKey и get. Обратите особое внимание на контракт от Javadoc :

... даже если все [отдельные] являются поточно-ориентированными, операции поиска не влекут за собой блокировку, а не поддерживает блокировку всей таблицы таким образом, чтобы это весь доступ ...

Операции получения (включая get) обычно не блокируются, поэтому могут перекрываться с операциями обновления (включая put и remove). Извлечение [например, containsKey или get] отражают результаты самых последних завершенных операций обновления , удерживающих их начало ...

Существует разница между «поточно-ориентированным» объектом и правильным использованием указанного объекта в параллельном контексте.

Удачного кодирования.

4 голосов
/ 30 января 2012

Как указано в ветке комментариев: нет, containsKey не удерживает запись каким-либо образом, поэтому более поздний вызов get(key) может вернуть null.Тем не менее, если вас интересует только логическое значение - это ключ на карте?- и вам не нужно получать ключ позже, тогда containsKey в порядке.

Кроме того, Map требуется интерфейс *1008*, так что это не так, как если быбудь там в любом случае.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...