Ответ
Нет, volatile не обеспечивает атомарность операций.
Что гарантирует volatile:
- Видимость изменений: Гарантирует, что все потоки увидят самое актуальное значение переменной. Запись в
volatile-переменную происходит в основную память, минуя кэши процессоров. - Запрет переупорядочивания: Компилятор и процессор не могут переупорядочить операции с
volatile-переменной относительно других операций чтения/записи.
Почему операции не атомарны? Сложные операции, такие как инкремент (i++), состоят из нескольких шагов (чтение, изменение, запись). Поток может быть прерван между этими шагами, что приводит к "потере" обновлений.
Пример проблемы:
volatile int counter = 0;
// Операция НЕ атомарна
counter++; // Эквивалентно: int temp = counter; temp = temp + 1; counter = temp;
Атомарные альтернативы:
- Классы из
java.util.concurrent.atomic:AtomicInteger atomicCounter = new AtomicInteger(0); atomicCounter.incrementAndGet(); // Атомарная операция -
Синхронизация:
private final Object lock = new Object(); private int counter = 0; public void increment() { synchronized(lock) { counter++; } }