Нужна ли статическая ConcurrentHashmap внешняя синхронизация - PullRequest
1 голос
/ 07 июля 2011

Требуется ли внешняя синхронизация статического ConcurrentHashmap с использованием блока синхронизации или блокировок?

Ответы [ 4 ]

2 голосов
/ 25 апреля 2012

Да и нет. Это зависит от того, что вы делаете. ConcurrentHashMap является потокобезопасным для всех своих методов (например, получить и положить). Тем не менее, не потокобезопасен для неатомарных операций. Вот пример метода, который выполняет неатомарную операцию:

public class Foo {
    Map<String, Object> map = new ConcurrentHashMap<String, Object>();

    public Object getFoo(String bar) {
        Object value = foo.get(bar);
        if (value == null) {
            value = new Object();
            map.put(bar, foo);
        }
        return value;
    }
}

Недостаток в том, что два потока могут вызывать getFoo для получения другого объекта. Помните, что при работе с любой структурой или типом данных, даже такими простыми, как int, неатомарные операции всегда требуют внешней синхронизации. Такие классы, как AtomicInteger и ConcurrentHashMap, помогают сделать поток некоторых общих операций безопасным, но не защищают от операций проверки-затем-установки, таких как getFoo выше.

1 голос
/ 07 июля 2011

Внешняя синхронизация требуется только в том случае, если вам нужно получить блокировку коллекции.Коллекция не раскрывает свои внутренние блокировки.

ConcurrentMap имеет putIfAbsent, однако, если создание объекта стоит дорого, вы можете не использовать это.

0 голосов
/ 07 июля 2011

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

Вкл. http://download.oracle.com/javase/1,5.0/docs/api/java/util/concurrent/ConcurrentHashMap.html в нем говорится:

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

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

Так что, если это не представляет каких-либо проблем в вашем конкретном приложении, вам не нужно беспокоиться об этом.

0 голосов
/ 07 июля 2011

Нет: внешняя синхронизация не требуется.

Все методы классов java.util.concurrent являются потокобезопасными.

...