В настоящее время я изучаю модель памяти Java и как она влияет на переупорядочивания, которые может сделать компилятор. Тем не менее, я немного смущен внешними операциями. JMM определяет их как действие, которое можно наблюдать за пределами операции. Отключение this question, я понимаю внешние действия, такие как печать значения, запись в файл, сетевые операции и т. Д.Переупорядочение внешних операций в модели памяти Java
Теперь, как внешние действия влияют на переупорядочение? Я думаю, что очевидно, что внешнее действие не может быть переупорядочено с помощью другого внешнего действия, так как это изменит наблюдаемое поведение программы (и, следовательно, не является допустимым преобразованием в соответствии с JMM). Но как насчет переупорядочения внешнего действия с нормальным доступом к памяти или действия синхронизации? Например:
volatile int v = 5;
int x = v;
System.out.println("!");
Можно распечатать и int x = v
быть заказана здесь? Я не вижу, как это меняет поведение, но чтение volatile v совпадает с просмотром монитора, поэтому я не думаю, что переупорядочение действительно.
Мое понимание (которое может быть ошибочным) заключается в том, что нет приоритета в отношении защищенных операций. Поэтому ни изменчивое чтение, ни внешняя запись не могут быть переупорядочены, поэтому ваш пример с тремя строками остается фиксированным. Вы можете протестировать его, вставив его в метод и называя его несколько (сотни?) Тысяч раз, используя оба -server и -XX: + PrintCompilation и сравнивая результаты JIT. – lscoughlin