существуетЕсли кто-то спросит вас, что такое модель памяти Java, отправьте ему эту статью.Мы представили, что для решения проблем атомарности, видимости и упорядочения в параллельном программировании язык Java предоставляет ряд ключевых слов, связанных с параллельной обработкой, таких какsynchronized
,volatile
,final
,concurren包
Ждать. существуетПредыдущая статьяВ статье мы также представляемsynchronized
использование и принципы. В этой статье разберем еще одно ключевое слово —volatile
.
Эта статья вращается вокругvolatile
развернуть, основное введениеvolatile
использование,volatile
принцип, иvolatile
Как обеспечить видимость и гарантии заказа и т. д.
volatile
Это ключевое слово есть не только в языке Java, но и во многих языках, и его использование и семантика также различаются. Особенно в языке C, C++ и Java естьvolatile
ключевые слова. может использоваться для объявления переменных или объектов. Ниже приведено краткое введение в язык Java.volatile
ключевые слова.
Использование изменчивого
volatile
Часто называют «легкимsynchronized
", также является относительно важным ключевым словом в параллельном программировании на Java. Иsynchronized
разные,volatile
это модификатор переменной, который можно использовать только для изменения переменных. Методы и блоки кода не могут быть изменены.
volatile
Использование относительно простое, просто используйте его при объявлении переменной, к которой могут обращаться несколько потоков одновременно.volatile
Просто исправьте это.
public class Singleton {
private volatile static Singleton singleton;
private Singleton (){}
public static Singleton getSingleton() {
if (singleton == null) {
synchronized (Singleton.class) {
if (singleton == null) {
singleton = new Singleton();
}
}
}
return singleton;
}
}
Приведенный выше код является типичной реализацией singleton в виде проверки двойной блокировки, которая используетvolatile
Ключевое слово украшает синглтон, к которому могут обращаться несколько потоков одновременно.
Принцип энергозависимости
существуетЕсли кто-то спросит вас, что такое модель памяти Java, отправьте ему эту статью.Мы представили, что для повышения скорости выполнения процессора между процессором и памятью для улучшения добавляется многоуровневый кеш. Однако из-за введения многоуровневого кеша возникает проблема несогласованности кэшированных данных.
Однако дляvolatile
переменная, когдаvolatile
Когда переменная записывается, JVM отправляет процессору инструкцию с префиксом блокировки для обратной записи переменной из кэша в основную память системы.
Однако, даже если оно будет записано обратно в память, если значение, кэшированное другими процессорами, все еще старое, возникнут проблемы при выполнении вычислительных операций, поэтому в многопроцессорных системах для обеспечения согласованности кэшей каждого процессора будет осуществляться.缓存一致性协议
Протокол когерентности кэша: Каждый процессор проверяет, не истек ли срок действия значения его собственного кеша, прослушивая данные, распространяющиеся по шине.Когда процессор обнаруживает, что адрес памяти, соответствующий его собственной строке кеша, был изменен, он устанавливает строку кеша текущего процессора to В недопустимом состоянии, когда процессор хочет изменить данные, он будет вынужден повторно прочитать данные из системной памяти в кэш процессора.
Итак, если переменнаяvolatile
В случае изменения его значение будет принудительно сбрасываться в основную память после каждого изменения данных. Кэши других процессоров также будут загружать значение этой переменной из основной памяти в свои собственные кеши, поскольку они соответствуют протоколу когерентности кеша. Это гарантируетvolatile
В параллельном программировании его значение отображается в нескольких кешах.
изменчивость и видимость
Видимость означает, что когда несколько потоков обращаются к одной и той же переменной, один поток изменяет значение переменной, а другие потоки могут сразу увидеть измененное значение.
мы вЕсли кто-то спросит вас, что такое модель памяти Java, отправьте ему эту статью.Проанализировано в: Модель памяти Java предусматривает, что все переменные хранятся в основной памяти, каждый поток имеет свою собственную рабочую память, а рабочая память потока сохраняет копию основной памяти, копию переменных, используемых в потоке, Все операции над переменными потоком должны выполняться в рабочей памяти и не могут напрямую читать или записывать в основную память. Разные потоки не могут напрямую обращаться к переменным в рабочей памяти друг друга, а передача переменных между потоками требует синхронизации данных между их собственной рабочей памятью и основной памятью. Поэтому может случиться так, что поток 1 изменяет значение переменной, а поток 2 невидим.
предыдущий оvolatile
Принцип был введен в Javavolatile
Ключевое слово предоставляет функцию, позволяющую синхронизировать измененную им переменную в основную память сразу после изменения, а изменяемую им переменную обновлять из основной памяти перед каждым использованием. Поэтому вы можете использоватьvolatile
Для обеспечения видимости переменных во время многопоточных операций.
изменчивый и упорядоченный
Порядок означает, что порядок выполнения программы соответствует порядку кода.
мы вЕсли кто-то спросит вас, что такое модель памяти Java, отправьте ему эту статью.Проанализировано в: Помимо введения временных интервалов, из-за оптимизации процессора и перестановки инструкций ЦП также может выполнять неупорядоченное выполнение входного кода, напримерload->add->save
может быть оптимизирован дляload->save->add
. Возможны проблемы с заказом.
иvolatile
Помимо обеспечения видимости данных, есть еще мощная функция, то есть он может запретить оптимизацию перестановки инструкций и так далее.
Обычные переменные лишь гарантируют, что правильный результат может быть получен в том месте, где результат присваивания зависит от выполнения метода, но не могут гарантировать, что последовательность операций присваивания переменной согласуется с последовательностью выполнения в программном коде.
Volatile может запрещать перестановку команд, что гарантирует выполнение программы кода в строгом соответствии с порядком кода. Это обеспечивает порядок. одеялоvolatile
Операция модифицированной переменной будет выполняться в строгом соответствии с порядком кода,load->add->save
Порядок выполнения такой: загрузить, добавить, сохранить.
изменчивость и атомарность
Атомарность означает, что операция непрерывна и должна выполняться полностью или не выполняться вообще.
мы вВ чем проблема многопоточности в параллельном программировании на Java?Проанализировано в: Поток является базовой единицей планирования ЦП. ЦП имеет концепцию кванта времени и будет планировать потоки в соответствии с различными алгоритмами планирования. Когда поток начинает выполняться после получения кванта времени, после того, как квант времени исчерпан, он теряет право использовать ЦП. Таким образом, в многопоточном сценарии проблемы с атомарностью будут возникать, поскольку временные срезы чередуются между потоками.
В предыдущей статье мы представилиsynchronized
Когда я упомянул, что для обеспечения атомарности необходимо передавать инструкции байт-кодаmonitorenter
иmonitorexit
,ноvolatile
Это не имеет ничего общего с этими двумя командами.
так,volatile
атомарность не гарантируется.
Может использоваться в следующих двух сценарияхvolatile
заменитьsynchronized
:
1. Результат операции не зависит от текущего значения переменной или может гарантировать, что только один поток изменит значение переменной.
2. Переменные не должны участвовать в инвариантных ограничениях с другими переменными состояния.
В дополнение к приведенным выше сценариям необходимо использовать другие методы для обеспечения атомарности, такие какsynchronized
илиconcurrent包
.
Давайте посмотрим на пример volatile и атомарности:
public class Test {
public volatile int inc = 0;
public void increase() {
inc++;
}
public static void main(String[] args) {
final Test test = new Test();
for(int i=0;i<10;i++){
new Thread(){
public void run() {
for(int j=0;j<1000;j++)
test.increase();
};
}.start();
}
while(Thread.activeCount()>1) //保证前面的线程都执行完
Thread.yield();
System.out.println(test.inc);
}
}
Приведенный выше код относительно прост, то есть нужно создать 10 потоков, а затем выполнить 1000 раз соответственно.i++
работать. При нормальных обстоятельствах выходной результат программы должен быть 10000, но все результаты многократного выполнения меньше 10000. Это на самом делеvolatile
Причина невозможности удовлетворить атомарность.
Почему это происходит, потому что хотя volatile может гарантироватьinc
Видимость между несколькими потоками. но не могуinc++
атомарность.
Резюме и размышления
мы представилиvolatile
ключевые слова иsynchronized
ключевые слова. Теперь мы знаем,synchronized
Атомарность, упорядоченность и видимость гарантируются. иvolatile
Но она может гарантировать только порядок и наглядность.
Затем давайте взглянем на синглтон, реализованный блокировкой с двойной проверкой, которая использоваласьsynchronized
, зачем тебе еще нужноvolatile
?
public class Singleton {
private volatile static Singleton singleton;
private Singleton (){}
public static Singleton getSingleton() {
if (singleton == null) {
synchronized (Singleton.class) {
if (singleton == null) {
singleton = new Singleton();
}
}
}
return singleton;
}
}
Ответ мы представим в следующей статье: Синхронизировано, он Shengliang изменчив, пожалуйста, обратите внимание на мой блог (www.hollischuang.com) и официальный аккаунт (Холлис).