Что такое ключевое слово volatile в Java и для чего оно используется?

«Что такое ключевое слово volatile в Java и для чего оно используется?» — вопрос из категории Java Core, который задают на 29% собеседований Java Разработчик. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

volatile — это ключевое слово в Java, которое гарантирует видимость изменений переменной для всех потоков. Оно предотвращает кэширование переменной в регистрах процессора или локальной памяти потока, обеспечивая чтение и запись непосредственно в/из основной (shared) памяти.

Основные свойства:

  • Гарантия happens-before: Запись в volatile-переменную происходит-до любого последующего чтения этой же переменной.
  • Не гарантирует атомарность: Операции типа count++ (чтение-изменение-запись) остаются неатомарными.
  • Запрещает переупорядочивание: Компилятор и процессор не могут переставить операции до/после доступа к volatile-переменной.

Типичный use case — флаг завершения:

public class Worker implements Runnable {
    private volatile boolean running = true;

    public void stop() {
        running = false; // Изменение видно другому потоку
    }

    @Override
    public void run() {
        while (running) { // Чтение всегда актуального значения
            // Работа
        }
    }
}

Когда использовать:

  • Для простых флагов или состояний (boolean, int), записываемых одним потоком.
  • Когда объект полностью инициализирован и публикуется другим потоком (паттерн безопасной публикации).

Когда НЕ использовать:

  • Для сложных составных операций. Вместо volatile используйте AtomicInteger, synchronized или Lock.