Ответ
Happens-before — это формальное отношение в Java Memory Model (JMM), которое гарантирует видимость и упорядоченность операций памяти между потоками. Если операция A happens-before операция B, то все изменения памяти, сделанные в A, будут видны потоку, выполняющему B.
Основные правила happens-before:
- Монитор (синхронизация): Освобождение монитора (выход из
synchronizedблока/метода) happens-before последующее захватывание того же монитора. - Volatile переменные: Запись в
volatile-поле happens-before каждое последующее чтение того же поля. - Запуск потока: Вызов
Thread.start()happens-before любые действия в запущенном потоке. - Завершение потока: Все действия в потоке happen-before возврат из
Thread.join()для этого потока. - Инициализация объекта: Завершение конструктора объекта happens-before начало любого финализатора (
finalize) для этого объекта.
Практический пример с volatile:
public class VisibilityExample {
private volatile boolean ready = false;
private int data = 0;
void writer() {
data = 42; // (1)
ready = true; // (2) volatile запись
}
void reader() {
if (ready) { // (3) volatile чтение
// Гарантированно увидит data = 42, так как (1) happens-before (2),
// а (2) happens-before (3) по правилу volatile.
System.out.println(data);
}
}
}
Без volatile компилятор или процессор могли бы переупорядочить операции (1) и (2), и поток reader мог бы увидеть ready = true, но data = 0.