Для чего используется ключевое слово volatile, synchronized, transient, native?
volatile
Модификатор volatile гарантирует две вещи:
- Видимость (visibility) – при записи
volatile-переменной значение немедленно сбрасывается в основную память, а при чтении – берётся из основной памяти, а не из кэша потока. Все потоки всегда видят актуальное значение. - Запрет переупорядочивания (ordering) – компилятор и процессор не могут переместить операции чтения/записи
volatile-переменной относительно других операций (создаётся memory barrier и устанавливается отношение happens-before).
Чего volatile НЕ гарантирует:
- Атомарность составных операций. Например,
count++надvolatile int count– это три операции (чтение, инкремент, запись), которые НЕ атомарны.
Когда достаточно volatile:
- Переменная-флаг (
volatile boolean running = true) - Паттерн «одна запись – много чтений»
- Публикация неизменяемого объекта
synchronized
Ключевое слово synchronized обеспечивает:
- Взаимное исключение (mutual exclusion) – только один поток может выполнять синхронизированный блок на одном мониторе одновременно.
- Видимость – при входе в
synchronizedблок поток обновляет свой кэш из основной памяти, при выходе – сбрасывает изменения в основную память. - Атомарность – все операции внутри
synchronizedблока выполняются как единое целое с точки зрения других потоков.
Пример
// Синхронизированный метод (монитор = this)
public synchronized void method() { /* ... */ }
// Синхронизированный блок (монитор = произвольный объект)
synchronized (lockObject) { /* ... */ }
// Статический синхронизированный метод (монитор = Class<?>)
public static synchronized void staticMethod() { /* ... */ }
transient
Ключевое слово transient к многопоточности отношения не имеет. Оно указывает, что поле класса не должно сериализоваться при использовании стандартной сериализации Java (Serializable).
native
Ключевое слово native к многопоточности также не относится. Оно указывает, что метод реализован в платформозависимом коде (обычно на C/C++) через механизм JNI (Java Native Interface).
Сравнение volatile и synchronized
| Характеристика | volatile |
synchronized |
|---|---|---|
| Видимость | Да | Да |
| Атомарность | Только для чтения/записи примитивов и ссылок | Да (весь блок) |
| Взаимное исключение | Нет | Да |
| Блокировка потока | Нет (неблокирующий) | Да (поток может быть заблокирован) |
| Область применения | Только переменные | Методы и блоки кода |
| Производительность | Выше | Ниже (из-за захвата/освобождения монитора) |
Аналогия из жизни.
volatile– это табло объявлений в аэропорту: все видят одну и ту же актуальную информацию, но никто не мешает двум сотрудникам одновременно попытаться обновить табло.synchronized– это кабинка с замком: только один человек может войти, и все изменения внутри будут завершены до того, как войдёт следующий.
На собеседовании. Этот вопрос – ловушка: кандидаты иногда начинают подробно рассказывать о
transientиnative, хотя к многопоточности они не относятся. Покажите, что понимаете разницу, и сосредоточьтесь наvolatileиsynchronized. Самый частый подвопрос: «Почемуvolatileне достаточно дляcount++?» Ответ: потому что инкремент – это три отдельные операции (read-modify-write), иvolatileне делает их атомарными.