Рассмотрим следующий многопоточный код, написанный на Java:JMM В практике
Общие переменные:
boolean n; // non-volatile
volatile boolean v; // volatile
темы 1:
v = true;
System.out.println("n=" + n);
Тема 2:
n = true;
System.out.println("v=" + v);
Предположим, изначально n = v = false
.
Сейчас:
- выход
v=false
Означает ли выходn=true
? - Что изменилось бы, если бы
n
были неустойчивыми? - Что бы изменилось, если
n
былиjava.util.List
(так чтоn = true
становитсяn.add("something")
и выходn=true
превращается в["something"]
)? - UPD3: Что делать, если
v
былиAtomicBoolean
и все считывание и пишет к нему осуществляется сcompareAndSet
семантическим?
Не могли бы вы утверждать свое положение в соответствии с моделью памяти Java?
UPD: Просьба обработать System.out.println("n=" + n)
как раз от n
. То же самое для v
.
UPD2: Не могли бы вы дать некоторый анализ 1-го и 4-го корпусов, как показано в JSR-133 сек. 8?
Проблема с такого рода анализов что они полностью игнорируют разрешенные переупорядочивания. Да, в мире последовательной согласованности это было бы правильно, но вы не можете получить это в Java - по крайней мере, не с изменчивым. Вы * можете * переупорядочивать волатильные чтения перед изменчивой записью, не нарушая JMM, и вдруг появляется еще несколько возможных путей, которые вы игнорировали. – Voo
@ Voo, это именно то, что я хочу видеть. Детальный анализ ситуации по JSR-133 сек. 8. Обновлен исходный вопрос. (Извините, что первоначально упомянул Андреаса, моя небрежность) – kalaider
@ Kalaider JSR длинный и невероятно формальный. Даже неофициальный анализ займет много времени - больше, чем я готов потратить. Легко сказать, что если вы используете не синхронизированный список, вы не можете писать в гонках с чем-то еще, поэтому по этой причине он будет сломан. – Voo