Видимость памяти в куче

Возьмите несинхронизированную карту

Map<Long,Long> map = new HashMap<>();

Когда мы делаем map.put(1,2) из одного потока, возможно ли, чтобы какой-то другой поток не видел это обновленное значение? Я понимаю, как примитивы и ссылки могут кэшироваться, и поэтому необходима синхронизация при доступе к ним. Но как насчет значений внутри самого объекта?

Итак, скажем, один поток делает:

map.put(1,2)

И другая нить делает

map.get(1)

Может ли этот поток увидеть null (при условии, что этот поток имеет обновленную ссылку на map)? Я предполагаю, что он всегда должен видеть обновленное значение, потому что объект не может быть кэширован ни одним потоком.


person Prashant Pandey    schedule 03.11.2020    source источник
comment
Да, это возможно. На самом деле все еще хуже: второй поток мог увидеть несогласованное состояние map с нарушенными инвариантами.   -  person Hulk    schedule 03.11.2020
comment
@ Халк, какие еще инварианты можно сломать? Кроме того, почему это происходит? Ясно, что в куче существует только одна копия объекта.   -  person Prashant Pandey    schedule 03.11.2020
comment
Например, может случиться так, что карта находится в процессе увеличения своей емкости для размещения значения, которое будет добавлено, когда другой поток получит к ней доступ. Таким образом, состояние карты уже не то, что было до вызова put, но и не то, что было после вызова put. Это где-то посередине: некоторые внутренние поля обновлены, а другие нет.   -  person Hulk    schedule 03.11.2020
comment
В основном это причина существования таких классов, как ConcurrentHashMap, которые предотвращают подобные проблемы.   -  person Hulk    schedule 03.11.2020
comment
Этот связанный вопрос охватывает, с какими проблемами вам все еще приходится сталкиваться, даже с ConcurrentHashMap: stackoverflow.com/questions/14947723/   -  person Hulk    schedule 03.11.2020
comment
Спасибо @Халк   -  person Prashant Pandey    schedule 03.11.2020
comment
Что касается HashMap и многопоточности, это может быть интересно прочитать: Из-за каких деталей реализации этот код так легко выходит из строя?   -  person Holger    schedule 25.11.2020