Флаг -server не меняет семантику выполнения. В вашем примере JVM, которая препятствовала бы выходу из цикла, была бы просто неправильной, как в «не соответствует спецификации Java», а также как и «просто неправильно».
Что может сделать оптимизация в целом и '-server' в частности, это изменить правила для неопределенного. Java довольно жестко определен, но у него есть несколько нечетких мест, в частности в отношении с плавающей запятой и несинхронизированного одновременного доступа к памяти.
Например, с таким кодом:
int x = 0, y = 0;
void set(int x, int y)
{
this.x = x;
this.y = y;
}
int getX()
{
return x;
}
int getY()
{
return y;
}
и предполагая, что некоторый код в потоке вызывает set (1, 1), а другой вызывает getY (), затем getX (), тогда без синхронизации getY () может вернуть 1 (новое значение) и getX () может вернуть 0 (старое значение): первый поток устанавливает x, затем y на уровне источника, но с точки зрения другого потока запись в y может произойти до записи в x.
Код, основанный на порядке обновления из другого потока без явной синхронизации (с «синхронизированным» или «изменчивым»), является ошибочным, но может избежать обнаружения с помощью тестов. Флаг -server делает JVM более удовлетворяющим триггеру при таком переупорядочении и, таким образом, может показывать ошибку. Но флаг -server здесь не ошибочен: код:
Это означает, что использование -server для тестирования на самом деле хорошая идея: это может помочь выявить некоторые ошибки. Для кода без ошибок флаг -server является безопасным.