Здравствуйте, Golovach Ivan, Вы писали:
GI>МММ ... Я еще раз пересмотрел 17-ю главу jls.third_edition [http://java.sun.com/docs/books/jls/third_edition/html/memory.html] и не обнаружил правила запрещающего следующее:
GI>Пусть один поток вызывает метод doIt() у общего объекта
GI>GI>class Shared {
GI> public volatile int vol = 0;
GI> public int nonvol = 0;
GI> public void doIt() {
GI> vol = 1;
GI> nonvol = 1;
GI> }
GI>}
GI>
GI>а второй поток проверяет условие у этого же общего объекта
GI>GI>Shared shared = ...
GI>if (shared.vol == 0 && shared.nonvol == 1) {...}
GI>
GI>и, как я понимаю, это условие МОЖЕТ ВЫПОЛНИТСЯ. Т.е. с точки зрения второго потока будет виден реордеринг записи vol и записи nonvol.
GI>Для себя я понял JMM так, что нельзя нарушать happend-before и casuality. Оно и не нарушается в данном примере.
GI>Вполне допускаю, что я не прав. Но тогда я заблуждаюсь искренне
.
GI>Вы могли бы обосновать свое мнения на моем примере основываясь на спецификации языка?
В приведенном примере указанное условие может выполниться не из-за reordering, а из-за обыкновенного race condition. Т.е. последовательность событий может быть такая:
Thread t1 calls doIt();
Thread t2 checks 'shared.vol == 0 (true)';
t1 executes 'vol = 1; nonvol = 1';
t2 checks 'shared.nonvol ==1 (true)';
В указанном примере happen-before вообще не работает, потому что
'nonvol = 1' выполняется
после записи в volatile-переменную.