РЕПЕТИТОР математика физика информатика
Для школьников и студентов. Подтягивание пробелов. ЦЭ, ЦТ, ОГЭ, ЕГЭ.
Идет набор на ЛЕТО. Жмите для подробностей:)
988 of 1163 menu

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

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

Синтаксис

volatile тип имяПеременной;

Пример

Давайте рассмотрим классический пример, в котором без volatile поток может никогда не увидеть изменение флага и зависнуть в бесконечном цикле. С volatile поток корректно завершит работу:

public class Main { static volatile boolean flag = false; public static void main(String[] args) throws InterruptedException { Thread worker = new Thread(() -> { while (!flag) { // waiting for flag to become true } System.out.println("Worker stopped"); }); worker.start(); Thread.sleep(100); flag = true; System.out.println("Flag set to true"); worker.join(); } }

Результат выполнения кода:

"Flag set to true" "Worker stopped"

Пример

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

public class Main { static volatile int counter = 0; public static void main(String[] args) throws InterruptedException { Runnable task = () -> { for (int i = 0; i < 10000; i++) { counter++; } }; Thread t1 = new Thread(task); Thread t2 = new Thread(task); t1.start(); t2.start(); t1.join(); t2.join(); System.out.println(counter); } }

Результат выполнения кода может быть, например, таким:

15342

Смотрите также

  • ключевое слово synchronized,
    которое обеспечивает и видимость, и атомарность
  • класс AtomicInteger,
    который даёт атомарные операции над числом
  • класс Thread,
    который представляет поток выполнения
  • метод join,
    который ожидает завершения потока
Мы используем cookie для работы сайта, аналитики и персонализации. Обработка данных происходит согласно Политике конфиденциальности.
принять все настроить отклонить