Неустойчивость: почему запрет на компилятор
В java, по моим сведениям, volatile variable делает поток, который читает/записывает поток непосредственно на главный CPU (не в кеше каждого потока), поэтому измените видимость на другие потоки.
Вещь, которую я не знаю, такова: поэтому, почему эта работа (из volatile) может помешать компиляции/переупорядочиванию кода кода.
спасибо:)
Ответы
Ответ 1
Вот очень хороший пример, иллюстрирующий проблему, запрет на переупорядочение направлен на решение (взято из здесь):
class VolatileExample {
int x = 0;
volatile boolean v = false;
public void writer() {
x = 42;
v = true;
}
public void reader() {
if (v == true) {
//uses x - guaranteed to see 42.
}
}
}
В этом примере v
является изменчивым, но x
- нет. Если сценарий и считыватель выполняются одновременно, и читатель видит, что v
установлен на true
, x
гарантированно будет 42
. До Java-5 компилятор был свободен, чтобы перезаписать записи в x
и v
, чтобы вы могли видеть x
в ноль после того, как вы увидели v
, установленный в true
. Это сбивало с толку и приводило к тонким ошибкам. Модель памяти Java-5 рассмотрела эту проблему, сделав волатильную запись почти эквивалентной синхронизации.
Ответ 2
Именно так определяется язык. Неофициально, отмечая переменную volatile
в Java, явным образом сообщает компилятору, что он не должен переупорядочивать утверждения вокруг него или оптимизировать его значение, поскольку это значение может быть изменено одновременно в другом потоке. Конкретная реализация JVM затем отвечает за соблюдение этого модификатора volatile
и принимает соответствующие меры предосторожности, чтобы некорректно оптимизировать программу.
Если вы хотите получить более подробную информацию о том, какие гарантии на уровне языка должны гарантировать правильность работы volatile
, вы можете посмотреть Java Language Specification описание модели памяти Java, которая определяет абстрактные правила, регулирующие поведение потоков. Он также описывает, как volatile
взаимодействует с этими правилами.
Надеюсь, это поможет!