Потокобезопасная карта с возможностью нулевого ключа - PullRequest
5 голосов
/ 18 апреля 2011

Мне нужен многопоточный объект Map для использования в кэшировании моего веб-сервера, и мне нужно иметь null ключи.

HashMap позволяет мне иметь нулевые ключи, а ConcurrentHashMap - нет. Я пытался создать синхронизированную версию HashMap, используя Collections.synchronizedMap(new HashMap()), но она также не принимает ключи null.

Есть ли альтернатива, которую я могу использовать, не прибегая к каким-либо способам обернуть null ключи?

Ответы [ 2 ]

7 голосов
/ 18 апреля 2011

Map, возвращаемое Collections.synchronizedMap, поддерживает все функции Map, которые вы ему предоставляете. Если вы дадите ему HashMap, он поддерживает ключ null (а также значения null, вы сказали "... мне нужно иметь" нулевые "значения ключа ..." , которые можно прочитать в любом случае). Что заставляет вас думать, что это не так?

Это работает как ожидалось, например:

import java.util.*;

public class MapTest
{
    public static final void main(String[] args)
    {
        Map map;

        try
        {
            map = Collections.synchronizedMap(new HashMap());
            map.put("one", "a");
            System.out.println("Size = " + map.size());
            map.put(null, "b");
            System.out.println("Size = " + map.size());
            System.out.println("map.get(null) = " + map.get(null));
        }
        catch (Exception ex)
        {
            System.out.println("Exception: " + ex.getMessage());
            ex.printStackTrace(System.out);
        }
        System.exit(0);
    }
}

Выход:

Size = 1
Size = 2
map.get(null) = b
2 голосов
/ 26 мая 2011

Насколько я знаю, нет ни простого способа сделать ConcurrentHashMap, ни эквивалентного класса, поддерживающего null ключи или значения.

ConcurrentHashMap очень отличается от Collections.synchronizedMap(new HashMap()).

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

Но более важным является то, что Iterator, возвращаемые синхронизированной картой, склонны выбрасывать ConcurrentModificationException, если базовая карта модифицируется при использовании итератора. С другой стороны, ConcurrentHashMap итераторы гарантированно никогда не сгенерируют ConcurrentModificationException, даже если базовая карта изменяется при использовании итератора.

...