Волатильное ключевое слово играет относительно важную роль в многопоточном языке Java. Основная функция летучих состоит в том, чтобы сохранить переменные, видимые в мультипотчике, и является самым легким механизмом синхронизации, предоставляемым в Java.
Видимость
Все переменные в модели памяти Java (переменные здесь являются глобальными переменными, а не локальными переменными. В методе нет проблем с защитой от потока, поскольку в основной памяти хранятся переменные, как называется метод). Каждый поток имеет свою собственную рабочую память. Каждый раз, когда поток выполняется, копия переменной будет получена из основной памяти, и операция переменной будет выполняться в рабочей памяти потока. Различные потоки не могут обмениваться рабочей памятью и могут прочитать копию переменной из основной памяти. В частности, это может быть выражен на рисунке ниже:
Однако для летучих (используя синхронизированные/конечные модификации, вышеупомянутое правило нарушается, то есть, когда поток изменяет значение переменной, другие потоки могут сразу узнать изменение переменной. Однако для обычных переменных, когда поток изменяет переменную, необходимо сначала нанести переменную в основную память, и другие потоки будут визбельны по всему, что на основной память, и это будет визуалеле, чтобы показать, что он будет отозвать, и это будет отображается по сравнению с указанием. Можно сделать вывод, что до тех пор, пока используется переменная, модифицированная летучкой, гарантировано, что переменная безопасна для работы в многопоточной среде, потому что она видно для рабочей памяти всех потоков, то есть.
открытый тест класса {частный статический летучий t = 0; private static int add () {return t ++; } public static void testvolatile () {for (int i = 0; i <20; i ++) {Thread Think = new Thread (()-> {for (int j = 0; j <1000; j ++) {add ();}}); Thread.Start (); } while (thread.activeCount ()> 1) {think.yield (); } System.out.println (t); } public static void main (string [] args) {testvolatile (); }}Ожидается, что значение t должно быть 20 000, но будет ситуация, когда значение t составляет менее 20 000. Вы должны догадаться причиной. Проблема заключается в T ++. T ++ не является атомной операцией. В Java операция T ++ означает сначала получить значение t, затем добавить 1, а затем назначить t. При получении значения T он изменяется летучим, поэтому можно получить последнее значение потока. Однако при добавлении 1 это не может быть гарантировано. Возможно, что другие потоки уже добавили 1.
Итак, какой сценарий наиболее подходит для использования волатильного?
* В операции переменной не зависит от текущего значения
* Переменные не должны участвовать в инвариантных ограничениях с другими переменными государства
Перевод на китайский означает, что для переменных, которые имеют как чтение, так и писать в многопоточных точках, вы можете использовать летучие для их изменения. Таким образом, вы не должны использовать операции блокировки/синхронизации для операций чтения. Чтение напрямую связано с тем, что переменные видны.