Здравствуйте, StanislavK, Вы писали:
SK>Все варианты возможны. В данном сценарии нет никаких ограничений.
SK>Если даже считывать ту же переменную, то все равно все будет так же, т.к. нет гарантии, что второй поток выполнится до присваивания volatile в первом.
SK>Еще момент, что компилятор в праве переупорядочить присваивания 'a' и 'flag' или придумать еще более страшную оптимизацию, так как они не volatile.
В том то и дело, что есть ограничения. Семантика volatile такова, что его нельзя реордерить, и его чтение/запись выступают в роли "полупроницаемых" барьеров. Поэтому для кода:
a = 1;
b = 1;
volatile = true;
... возможны только два варианта выполнения:
a = 1;
b = 1;
volatile = true;
или
b = 1;
a = 1;
volatile = true;
Третьего не дано, запись в a и b гарантированно будет произведена до записи в volatile. Но для кода:
a = 1;
b = 1;
volatile = true;
c = 1;
... запись в с может быть произведена до записи в volatile (полупроницаемость).
Для volatile read все с точностью наоборот: код может пролезть "сверху", но не "снизу".