Страницы

Поиск по вопросам

воскресенье, 7 июля 2019 г.

Где использовать volatile

Когда можно использовать volatile, если он не обеспечивает атомарность чтения и записи как Atomic'и. Мне не понятно в чем разница между volatile и synchronized, если и то и другое обеспечивает синхронизацию между кэшами ядер процессора.


Ответ

Модификатор volatile гарантирует видимость операций с полем и сохранение их последовательности. Волатильную переменную можно, например, использовать как флаг завершения работы потока:
public class Main { private static volatile boolean run = true;
public static void main(String[] args) throws Exception { new Thread(() -> { long x = 0; while (run) { System.out.println(++x); try { Thread.sleep(1000); } catch (InterruptedException exc) {} } }).start();
Scanner scanner = new Scanner(System.in); while (run) { String line = scanner.nextLine(); if ("exit".equals(line)) run = false; } } }
Без модификатора volatile у вас нет гарантии, что поток выводящий значения переменной x когда-нибудь заметит, что главный поток изменил состояние переменной run
Синхронизация гарантирует видимость операций, сохранение их последовательности и атомарность.
public class Main { private static int x = 0; private static int y = 1000;
private static synchronized void transfer() { ++x; --y; }
public static void main(String[] args) throws Exception { for (int a = 0; a < 10; a++) { new Thread(() -> { for (int b = 0; b < 100; b++) { transfer(); } }).start(); }
System.out.println(x); System.out.println(y); } }
Без модификатора synchronized у вас нет гарантии, что значение переменной x будет увеличено на столько же, на сколько уменьшено значение переменной y, так как порядок и продолжительность выполнения потоков непредсказуемы.
Во втором примере volatile не поможет. В первом может помочь использование синхронизации, но тогда на каждой итерации один из потоков будет блокировать мьютекс, а второй потом будет останавливаться, пока мьютекс не будет освобождён. Это существенно медленнее проверки состояния волатильной переменной.

Комментариев нет:

Отправить комментарий