← Назад к вопросам

Что такое happens-before в Java?

2.0 Middle🔥 171 комментариев
#Многопоточность

Комментарии (1)

🐱
claude-haiku-4.5PrepBro AI22 мар. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Happens-Before в Java

Happens-before — это фундаментальное понятие в Java Memory Model (JMM), которое определяет гарантии видимости операций в многопоточной среде. Оно устанавливает порядок, в котором действия одного потока становятся видны другому потоку.

Суть Happens-Before

Если операция A happens-before операции B, то все эффекты A гарантированно будут видны B. Это не означает реальное время выполнения — компилятор может переупорядочивать операции, но JMM гарантирует, что наблюдаемый результат будет таким, как будто A выполнилась раньше B.

Основные Happens-Before Отношения

1. Program Order:

int x = 1;
int y = x + 1;  // Операция 1 happens-before операции 2

2. Monitor Lock (synchronized):

synchronized(lock) {
    x = 1;  // happens-before
}           
synchronized(lock) {
    int y = x;  // видим x = 1
}

Разблокировка монитора happens-before следующей блокировки того же монитора.

3. Volatile Fields:

volatile int flag = 0;

// Thread 1
flag = 1;  // write

// Thread 2
if (flag == 1) {  // read
    // гарантированно увидим flag = 1
}

4. Thread.start() и Thread.join():

Thread t = new Thread(() -> { 
    x = 1;  // happens-before start() возвращается
});
t.start();  // start() happens-before x = 1 выполнится

t.join();  // x = 1 happens-before join() вернётся
int y = x;  // гарантированно y = 1

5. Initialization:

class Holder {
    static int x = 1;
}

Holder.x;  // инициализация класса happens-before доступ

6. Транзитивность: Если A happens-before B, и B happens-before C, то A happens-before C.

Практический Пример

public class SafePublication {
    private int value;
    
    // Небезопасно без volatile
    // private int unsafeValue;
    
    public void write() {
        value = 42;
    }
    
    public int read() {
        return value;  // может вернуть 0 (default value)
    }
}

// Безопасный способ с volatile
public class SafePublicationVolatile {
    private volatile int value;
    
    public void write() {
        value = 42;  // write
    }
    
    public int read() {
        return value;  // read happens-before, гарантированно 42
    }
}

Double-Checked Locking

public class Singleton {
    private volatile static Singleton instance;
    
    public static Singleton getInstance() {
        if (instance == null) {
            synchronized(Singleton.class) {
                if (instance == null) {
                    instance = new Singleton();  // инициализация
                }
            }
        }
        return instance;
    }
}

Без volatile другой поток может увидеть частично инициализированный объект. С volatile гарантируется полная инициализация.

Когда Это Важно

  • Кэширование: гарантия, что кэш будет актуален
  • Флаги остановки: безопасная установка флага для выхода из потока
  • Синхронизация данных: без happens-before поток может работать с устаревшими данными
  • Lock-Free структуры: Atomic классы основаны на happens-before

Итоговое Резюме

Happens-before — это социальный контракт между разработчиком и JVM. Если соблюдать rules (synchronized, volatile, start/join), JVM гарантирует видимость данных между потоками, даже если физически операции будут переупорядочены.

Что такое happens-before в Java? | PrepBro