ГлавнаяБлог › happens-before в Java: модель памяти простыми словами

happens-before в Java: модель памяти простыми словами

Проблема: видимость и переупорядочивание

Компилятор, JIT и процессор могут переставлять операции и держать значения в кэшах/регистрах ради скорости. Внутри одного потока это незаметно. Но другой поток может увидеть изменения «не в том порядке» или не увидеть вовсе.

Что такое happens-before

happens-before — это отношение «гарантированно раньше и видимо»: если действие A happens-before B, то результат A виден в B, и компилятор не переставит их местами. Это не про физическое время — про гарантии видимости.

Аналогия: эстафета. Пока не передал палочку (не установил happens-before), следующий бегун не имеет права стартовать и видеть, что ты пробежал. Передача палочки — это volatile-запись/выход из synchronized.

Как установить happens-before

  • volatile: запись в volatile happens-before последующего чтения этой переменной.
  • synchronized: выход из блока (release lock) happens-before входа в блок по тому же монитору.
  • final-поля: корректно опубликованный объект гарантирует видимость своих final-полей после конструктора.
  • Thread.start() happens-before кода потока; код потока happens-before join().
Без одного из этих «мостиков» никакой гарантии нет: цикл while(!flag){} с обычным boolean flag может крутиться вечно, даже если другой поток выставил flag=true — изменение просто не станет видимым.

Частые вопросы

— Что такое happens-before?
Гарантия, что результат одного действия виден другому и порядок не переставят. Устанавливается volatile/synchronized/final/start-join.
— Зачем volatile для флага остановки?
Чтобы запись флага в одном потоке стала видимой в цикле другого — без volatile изменение может «застрять» в кэше.

Ещё разборы