Логотип YeaHub

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

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

Тренажёр

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

Обучение

Навыки

Войти

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

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

© 2026 YeaHub

Документы

Медиа

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

В чем отличие volatile от synchronized?

Вопрос проверяет понимание механизмов обеспечения видимости изменений и атомарности операций в многопоточном программировании на Java, что необходимо для написания корректных конкурентных программ.

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

Ключевое слово volatile гарантирует видимость изменений переменной для всех потоков, но не обеспечивает атомарность составных операций. Ключевое слово synchronized обеспечивает и видимость, и атомарность, блокируя доступ к блоку кода или методу для других потоков. Volatile подходит для простых флагов или переменных, где важен только факт изменения. Synchronized используется для защиты критических секций, где несколько операций должны выполняться как единое целое.

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

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

Ключевое слово volatile

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

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

public class Example {
    private volatile int counter = 0;
    // НЕПРАВИЛЬНО! Инкремент не атомарен.
    public void increment() {
        counter++; // Чтение, увеличение, запись — возможна потеря обновлений.
    }
}

Ключевое слово synchronized

Модификатор synchronized используется для создания критических секций. Он обеспечивает и взаимное исключение (mutual exclusion), и видимость изменений. Когда поток входит в synchronized-блок или метод, он захватывает монитор объекта (или класса). Это гарантирует, что в данный момент времени только один поток может выполнять этот код. Кроме того, при выходе из synchronized-секции все изменения, сделанные в локальной памяти потока, сбрасываются в основную память, а при входе — значения переменных читаются из основной памяти. Это решает обе проблемы.

public class Example {
    private int counter = 0;
    // ПРАВИЛЬНО. Операция защищена.
    public synchronized void increment() {
        counter++; // Теперь атомарно и видимо.
    }
}

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

  • Используйте volatile для простых флагов состояния (boolean isRunning), переменных-счетчиков, которые только записываются одним потоком, или объектов, публикация которых происходит безопасно (например, ссылка на immutable-объект).
  • Используйте synchronized (или более современные средства из пакета java.util.concurrent) когда вам нужна атомарность составных операций или защита доступа к общему изменяемому состоянию, которое читается и пишется несколькими потоками.

Вывод: volatile — это инструмент для обеспечения видимости, а synchronized — для обеспечения атомарности и взаимного исключения. Выбор зависит от того, нужно ли вам просто сообщить другим потокам об изменении значения или необходимо гарантировать, что последовательность операций будет выполнена без вмешательства извне.

Уровень

  • Рейтинг:

    4

  • Сложность:

    6

Навыки

  • Java

    Java

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

#Java

#volatile

#synchronized

#concurrency

#thread safety

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