Параллелизм: HashMap и списки как значение

Предположим, у меня есть Synchronized HashMap, в котором String используется в качестве ключа, а список — в качестве значения.

Map<String, List<Object>> map = Collections.synchronizedMap(new HashMap<String, List<Object>>());

Будет ли этот список потокобезопасным? Например, если я сделаю это:

List<Object> list = map.get("whatever"); // Supposing I get a List
list.add(new Object()); // Would this be thread-safe?

В противном случае, будет ли это с ConcurrentHashMap вместо синхронизированного? Или единственный способ избежать условий гонки — преобразовать его в CopyOnWriteArrayList?


person jacosro    schedule 08.12.2016    source источник
comment
Нет, только Map является потокобезопасным как для synchronizedMap(), так и для ConcurrentHashMap.   -  person Andreas    schedule 09.12.2016
comment
Вы добавляете элементы в объект list, который не имеет ничего общего с синхронизированной картой, которая просто содержит его. Сам список должен быть синхронизированной коллекцией.   -  person radoh    schedule 09.12.2016
comment
Что делать, если у Map еще нет List для данного ключа? Вы не можете просто позвонить map.put(), потому что мир мог измениться между звонком get() и звонком put().   -  person Andreas    schedule 09.12.2016


Ответы (1)


Collections.synchronizedMap обеспечит потокобезопасность только для результирующей карты. Если вы хотите сделать значения карты потокобезопасными, почему бы не украсить свои списки, например:

Collections.synchronizedList(yourList)

а потом добавить их на карту?

person uylmz    schedule 08.12.2016
comment
Я ожидал этого, я просто хотел быть уверенным в этом, поэтому я буду использовать CopyOnWriteArrayList - person jacosro; 09.12.2016