Ответ 1
Обоснование семантики volatile
коренится в Java Memory Model, которая указана в терминах действий:
- читает и записывает в переменные
- блокировки и разблокировки мониторов
- начало и соединение с потоками
Модель памяти Java определяет частичное упорядочение, называемое происходит-до для действий, которые могут возникать в Java программа. Обычно нет гарантии, что потоки могут видеть результаты друг друга.
Скажем, у вас есть два действия A и B. Чтобы гарантировать, что поток, выполняющий действие B, может видеть результаты действия A, должно быть отношение происходит до между A и B. Если нет, JVM может быть переупорядочивать их по своему усмотрению.
Программа, которая неправильно синхронизирована, может иметь расы данных. Готовность данных происходит, когда переменная считывается с помощью > 1 потоков и записывается с помощью >= 1 потока (-ов), но операции чтения и записи не упорядочиваются с помощью упорядоченного порядка.
Следовательно, правильно синхронизированная программа не имеет расов данных, и все действия внутри программы происходят в фиксированном порядке.
Таким образом, действия обычно упорядочены только частично, но также существует общий порядок:
- фиксация и выпуск блокировки
- читает и записывает переменные volatile
Эти действия полностью упорядочены.
Это делает разумным описать случившееся - раньше в терминах "последующих" блокировок и чтения изменчивых переменных.
Относительно ваших вопросов:
- С отношениями "бывшее-до" у вас есть альтернативное определение
volatile
- Реверсирование порядка не имеет смысла для определения выше, тем более, что существует общий порядок.
Это иллюстрирует связь между событиями, когда два потока синхронизируются с использованием общей блокировки . Все действия в потоке A упорядочены по правилу заказа программы, равно как и действия в потоке B. Поскольку A освобождает блокировку M и B впоследствии, получает M, все действия в перед освобождением блокировки, поэтому упорядочен до действий в B после приобретения блокировки. Когда два потока синхронизируются с разными блокировками, мы ничего не можем сказать о упорядочении действий между ними, так как это не происходит - до отношения между действиями в двух потоках.
Источник: Java Concurrency на практике