Является ли запись в энергозависимый барьер памяти в Java
Недавно я слышал в своем выступлении, что запись в volatile вызывает барьер памяти для каждой переменной, в которую записан поток. Это действительно правильно? Из JLS кажется, что сбрасывается только соответствующая переменная, но не другие. Кто-нибудь знает, что на самом деле правильно? Можно ли указать мне конкретное место в JLS?
2 ответа
Ссылка на переменные типа Volatile и другие переменные была правильной. Я не осознавал, что транзитивность "происходит раньше" - это то, что должно быть реализовано виртуальной машиной, а не то, что следует из определения. Я все еще озадачен, почему что-то с такими далеко идущими последствиями не указано четко, но на самом деле является следствием некоторого определения. Подведем итоги. Предположим, у вас есть 4 действия:
thread1 thread2
a1
a2
a3
a4
где a2 - запись в энергозависимую переменную v, а a3 - чтение из той же энергозависимой переменной v. Из определения случившегося до (hb) следует, что hb(a1,a2) и hb(a3,a4). Также для летучих мы имеем hb(a2,a3). Теперь из требуемой транзитивности hb следует, что hb(a1,a3). Таким образом, запись и последующее чтение энергозависимой переменной v выполняет функцию барьера памяти.
Да, это создаст барьер. Вы можете прочитать больше здесь. Существует 4 типа: LoadLoad LoadStore StoreStore StoreLoad.
Насколько ваш вопрос
Из JLS кажется, что сбрасывается только соответствующая переменная, но не другие. Кто-нибудь знает, что на самом деле правильно?
Все записи, происходящие до того, как энергозависимое хранилище, будут видны любым другим потокам с предикатом, что другие потоки загружают это новое хранилище. Однако записи, которые происходят до того, как энергозависимая нагрузка может или не могут быть замечены другими потоками, если они не загружают новое значение.
Для практического примера
volatile int a =0;
int b = 0;
Thread-1
b = 10;
a = 3;
Thread-2
if(a == 0){
// b can b 10 or 0
}
if(a == 3){
// b is guaranteed to be 10 (according to the JMM)
}