Какая модель памяти в Java
Что проверяют
Понимаете ли вы, что модель памяти это правила видимости и упорядочивания, а не карта областей кучи. Вопрос звучит просто, но ответ про Eden и Survivor будет мимо.
Как отвечать
Модель памяти Java (JMM) описывает, при каких условиях запись, сделанная одним потоком, гарантированно видна другому, и какие перестановки операций допустимы для компилятора и процессора.
Проблема в том, что без синхронизации оптимизации разрешены: значение может остаться в регистре или в кэше ядра, а порядок инструкций измениться. Поэтому другой поток способен вообще не увидеть изменения или увидеть его не в том порядке.
Центральное понятие это отношение «происходит раньше» (happens-before). Если действие A происходит раньше B, то результат A виден в B. Оно устанавливается:
- освобождением и захватом одного монитора (
synchronized); - записью и последующим чтением
volatile; - запуском потока (
start) относительно всего, что было до него, и завершением (join) относительно всего, что было в потоке; - инициализацией
finalполей в конструкторе, что и делает неизменяемые объекты безопасными для публикации.
Практический вывод: без установленного отношения нет никаких гарантий. Отсюда правила: разделяемое изменяемое состояние защищают синхронизацией; volatile даёт видимость, но не атомарность; неизменяемые объекты безопасны без всякой синхронизации; двойная проверка блокировки без volatile некорректна.
Где спотыкаются
Рассказывают про поколения кучи вместо правил видимости.
Считают volatile заменой блокировки.
Не могут объяснить, почему без синхронизации поток может не увидеть изменение вообще никогда.
Не знают про гарантии final полей.