Назад к вопросам
Middle
81
questionbank

В чем разница между volatile и атомарными переменными?

Sobes Copilot

Получайте ответы в реальном времени

Ответ от нейросети

sobes.tech AI

volatile обеспечивает видимость изменений переменной для разных потоков и запрещает компилятору и JVM переупорядочивать инструкции, связанные с этой переменной. Это гарантирует, что при чтении volatile переменной поток увидит самое последнее записанное значение. Однако volatile не гарантирует атомарность составных операций (например, инкремента).

Атомарные классы из пакета java.util.concurrent.atomic (например, AtomicInteger, AtomicLong, AtomicReference) используют низкоуровневые атомарные операции, такие как Compare-And-Swap (CAS), которые выполняются на аппаратном уровне. Они гарантируют, что операции чтения-изменения-записи выполняются атомарно, без необходимости явной синхронизации с использованием synchronized.

Сравнение:

Признак volatile Атомарные переменные (AtomicInteger и т.д.)
Атомарность Не гарантирует атомарность составных операций. Гарантируют атомарность операций (CAS).
Видимость Гарантирует видимость изменений для других потоков. Гарантируют видимость (побочный эффект CAS).
Использование Для обеспечения видимости простого чтения/записи. Для атомарных операций типа инкремента, CAS.
Накладные расходы Меньше накладных расходов, чем у synchronized. Обычно меньше накладных расходов, чем у synchronized в условиях низкой конкуренции.

Пример использования volatile:

class SharedData {
    volatile boolean flag = false; // Обеспечивает видимость изменения flag

    public void setFlag() {
        flag = true;
    }

    public boolean isFlag() {
        return flag;
    }
}

Пример использования AtomicInteger:

import java.util.concurrent.atomic.AtomicInteger;

class Counter {
    AtomicInteger count = new AtomicInteger(0); // Атомарный счетчик

    public void increment() {
        count.incrementAndGet(); // Атомарное инкрементирование
    }

    public int getCount() {
        return count.get();
    }
}