Следующий пример показывает, когда y
может быть 0
.
class FinalFieldExample {
final int x;
int y;
static FinalFieldExample f;
FinalFieldExample() {
x = 3;
f = this;
for (int i = 0; i < 1000000; i++) {
// simulate processing
}
y = 4;
}
static void writer() {
new FinalFieldExample();
}
static void reader() {
System.out.println(f.x); // guaranteed to see 3
System.out.println(f.y); // could see 0
}
public static void main(String[] args) {
new Thread(FinalFieldExample::writer).start();
new Thread(FinalFieldExample::reader).start();
}
}
Обратите внимание, что это не вызвано повторным вызовом инициализации компилятором JIT. Проблема возникает из-за того, что this
был опубликован или, скорее, стал видимым для других потоков во время создания. Здесь - это пост о той же документации JLS и похожем примере.
Чтобы создать пример, показывающий эту проблему, вызванную переупорядочением, вам необходимо понять, как переупорядочение работает, но это не так. детерминированность c вещь. Здесь кто-то опубликовал очень хороший ответ, который объясняет переупорядочение и связал множество ресурсов.
Детали того, что JIT может или будет делать, недетерминированы c. Просмотр миллионов образцов прогонов не даст значимого шаблона, поскольку переупорядочения носят субъективный характер и зависят от очень специфических деталей c, таких как дуга процессора, время, эвристика, размер графика, поставщик JVM, размер байт-кода и т. Д. c. Мы знаем только, что JIT будет предполагать, что код выполняется в однопоточной среде, когда ему не нужно соответствовать JMM. В конце концов, JIT мало что значит для вашего многопоточного кода.
Очень трудно создать пример, где ваш код «ломается» из-за переупорядочения. JIT-компилятор, очевидно, будет проверять все, что вы делаете в своем коде, и не будет выполнять повторные операции, когда они «сломают» логи c. Вы правы, что это может произойти в некоторых редких ситуациях .
Здесь и здесь некоторые люди создали примеры, которые показывают переупорядочение. Вы можете видеть, что это очень низкий уровень i sh эффекта. Документация только говорит, что это может случиться, но не объясняет когда . Вы не должны воспринимать это как «правило», о котором вам нужно знать. Это просто дополнительная информация для вас.