Какое ключевое слово «volatile» используется для

Я прочитал несколько статей о ключевом слове volatile , но я не смог понять, как его правильно использовать. Не могли бы вы сказать мне, для чего он должен использоваться в C # и в Java?

118
задан Cody Gray 13 May 2012 в 10:07
поделиться

4 ответа

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

83
ответ дан 24 November 2019 в 01:53
поделиться

В Java "volatile" используется, чтобы сообщить JVM, что переменная может использоваться несколькими потоками одновременно, поэтому некоторые общие оптимизации не могут быть применены.

Примечательно ситуация, когда два потока, обращающиеся к одной и той же переменной, работают на разных ЦП на одной машине. Процессоры очень часто агрессивно кэшируют данные, которые он хранит, потому что доступ к памяти намного медленнее, чем доступ к кешу. Это означает, что если данные обновлены в CPU1, они должны немедленно пройти через все кеши и в основную память, а не тогда, когда кеш решает очистить себя, чтобы CPU2 мог видеть обновленное значение (опять же, игнорируя все тайники в пути).

9
ответ дан 24 November 2019 в 01:53
поделиться

Ключевое слово volatile имеет разные значения как в Java, так и в C #.

Java

Из Спецификации языка Java :

Поле может быть объявлено энергозависимым, и в этом случае модель памяти Java гарантирует, что все потоки видят согласованное значение переменной.

C #

Из справочника C # по ключевому слову volatile :

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

34
ответ дан 24 November 2019 в 01:53
поделиться

Рассмотрим этот пример:

int i = 5;
System.out.println(i);

Компилятор может оптимизировать это, чтобы просто вывести 5, вот так:

System.out.println(5);

Однако, если есть другой поток, который может изменить i, это неправильное поведение. Если другой поток изменит i на 6, оптимизированная версия все равно выведет 5.

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

159
ответ дан 24 November 2019 в 01:53
поделиться