Ответ 1
Ответ на ваш вопрос находится в JLS # 17.4.5:
Записывается в нестабильное поле (§8.3.1.4) - перед каждым последующим чтением этого поля.
Итак, если в одном потоке вы
aNonVolatileVariable = 2 //w1
aVolatileVariable = 5 //w2
И затем в другом потоке:
someVariable = aVolatileVariable //r1
anotherOne = aNonVolatileVariable //r2
У вас есть гарантия, что anotherOne
будет равно 2, даже если эта переменная нестабильна. Так что да, использование volatile также имеет побочные эффекты для использования энергонезависимых переменных.
Более подробно это связано с двумя другими гарантиями, предоставленными моделью памяти Java (JMM) в том же разделе: порядок и транзитивность внутри потока (hb (x, y) означает, что x происходит до y):
Если x и y - действия одного и того же потока, а x - до y в программном порядке, то hb (x, y).
[...]
Если hb (x, y) и hb (y, z), то hb (x, z).
В моем примере:
- hb (w1, w2) и hb (r1, r2) (семантика внутри потока)
- hb (w2, r1) из-за неустойчивой гарантии
поэтому вы можете заключить, что hb (w1, r2) транзитивностью.
И JMM гарантирует, что все исполнения программы будут последовательно согласованы (т.е. будут выглядеть так, как будто ничего не было переупорядочено), если они правильно синхронизированы с событиями-до отношений. Таким образом, в этом конкретном случае в режиме энергонезависимого чтения гарантируется эффект от энергонезависимой записи.