Сначала ответь вслух
Скажи ответ вслух хотя бы пару минут, потом открой эталон и сравни. Эталон открыт всем и не требует входа.
Показать ответ
Эталонный ответ
Модель памяти Java описывает не «когда значение попадёт в память», а порядок, который обязана соблюдать реализация. Если действие A происходит-раньше действия B, всё записанное до A видно в B.
- Порядок программы внутри одного потока.
- Освобождение монитора — перед последующим захватом того же монитора.
Thread.start()— перед действиями запущенного потока; действия потока — перед возвратом из егоjoin().- Запись final-полей в конструкторе — перед чтением этих полей через корректно опубликованную ссылку.
- Классы java.util.concurrent: положить в очередь или карту — перед тем, как другой поток это достанет; отправить задачу в executor — перед её выполнением; завершение задачи — перед возвратом из
Future.get().
Как у тебя получилось?
Уточняющие вопросы
Так обычно копают глубже. Раскрой строку, когда ответишь вслух.
Уточнение 1-го уровня: Видна ли запись под synchronized потоку, который читает без блокировки?
Ответ уровня Senior
Нет: гарантия есть только между освобождением и захватом одного и того же монитора. Читатель без захвата может увидеть старое значение.
Типичные ошибки
- Говорить о «сбросе кэша в память» вместо отношения порядка.
- Синхронизировать запись и забывать синхронизировать чтение.
Первоисточники
Быстрые задания по теме
boolean flag;
void stop() { flag = true; }
void run() { while (!flag) { } }Проверь себя
Задание 1 из 1Поток A пишет в поле flag, поток B читает его в цикле. Что нужно, чтобы B гарантированно увидел запись?