Ответ
Ключевое слово volatile гарантирует две важные вещи в многопоточном программировании Java:
- Видимость изменений (Memory Visibility): Запись в
volatile-переменную одним потоком становится немедленно видна всем другим потокам. Безvolatileизменения могут остаться в локальном кэше процессора потока. - Запрет переупорядочивания (Prevents Reordering): Компилятору и процессору запрещено переставлять операции чтения/записи
volatile-переменной относительно других операций с памятью, что обеспечивает соблюдение happens-before.
Типичный use-case — флаг остановки потока:
public class WorkerThread implements Runnable {
private volatile boolean running = true;
public void run() {
while (running) { // Чтение всегда увидит последнее значение
// выполнение работы
}
}
public void stop() {
running = false; // Запись видна потоку run() немедленно
}
}
Что volatile НЕ гарантирует:
- Атомарность составных операций: Операции вроде
count++(чтение-изменение-запись) не атомарны, даже еслиcountобъявлен какvolatile. Для этого нужныAtomicInteger,synchronizedилиLock.
Когда использовать volatile:
- Простые флаги состояния (
boolean flag). - Переменные, записываемые одним потоком и читаемые многими (например, конфигурация).
- Объекты, публикуемые безопасным способом (safe publication) через
volatile-ссылку.
Альтернативы для сложных сценариев: java.util.concurrent.atomic, synchronized, Lock.