Логотип YeaHub

База вопросов

Собеседования

Тренажёр

База ресурсов

Обучение

Навыки

Войти

Выбери, каким будет IT завтра — вместе c нами!

YeaHub — это полностью открытый проект, призванный объединить и улучшить IT-сферу. Наш исходный код доступен для просмотра на GitHub. Дизайн проекта также открыт для ознакомления в Figma.

© 2026 YeaHub

Документы

Медиа

Назад
Вопрос про Java: volatile, Java, concurrency, memory visibility, thread safety

Для чего используется volatile?

Вопрос проверяет понимание ключевого слова volatile в Java, которое используется для обеспечения видимости изменений переменной между потоками.

Короткий ответ

Ключевое слово volatile в Java гарантирует, что чтение и запись переменной будут происходить непосредственно из/в основную память, минуя кэши процессоров. Это обеспечивает видимость изменений переменной для всех потоков. Однако volatile не гарантирует атомарность составных операций (например, инкремента). Его используют для флагов завершения или простых состояний, где важна своевременная видимость изменений.

Длинный ответ

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

Как работает volatile?

Когда переменная объявлена как volatile, компилятор и JVM получают следующие гарантии:

  • Видимость: Любая запись в volatile-переменную немедленно становится видимой для всех других потоков. Чтение volatile-переменной всегда возвращает самое последнее записанное значение.
  • Запрет переупорядочивания: Операции чтения/записи volatile-переменной не могут быть переупорядочены с другими операциями чтения/записи памяти, что создает частичный барьер памяти (memory barrier).

Где применяется volatile?

Типичные сценарии использования:

  • Флаги завершения работы потока (например, boolean running = true).
  • Простые однократно записываемые состояния (например, результат инициализации).
  • Ссылки на объекты, публикуемые безопасным образом (safe publication).

Пример кода

public class WorkerThread extends Thread {
    private volatile boolean running = true;

    public void run() {
        while (running) {
            // Выполняем работу
        }
    }

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

Ограничения volatile

Важно помнить, что volatile не обеспечивает атомарность операций. Например, операция инкремента count++ состоит из чтения, изменения и записи. Если два потока одновременно инкрементируют одну volatile-переменную, может произойти потеря обновления. Для таких случаев нужны атомарные классы (например, AtomicInteger) или синхронизация.

Вывод: Используйте volatile для простых переменных состояния, где важна мгновенная видимость изменений между потоками, но операции над ними атомарны по своей природе (например, простая запись). Для составных операций выбирайте другие механизмы синхронизации.

Уровень

  • Рейтинг:

    4

  • Сложность:

    6

Навыки

  • Java

    Java

Ключевые слова

#volatile

#Java

#concurrency

#memory visibility

#thread safety

Подпишись на Java Developer в телеграм