El autor asume allí que la variable done
es una variable local, que no tiene ningún requisito en el Modelo de memoria Java para exponer su valor a otros hilos sin primitivas de sincronización. O dicho de otra manera: el valor de done
no cambiará ni será visto por ningún código que no sea el que se muestra aquí.
En ese caso, dado que el bucle no cambia el valor de done
, su valor puede ignorarse efectivamente, y el compilador puede levantar la evaluación de esa variable fuera del bucle, evitando que se evalúe en el "hot "parte del ciclo. Esto hace que el ciclo funcione más rápido porque tiene que hacer menos trabajo.
Esto funciona en las expresiones más complicadas también, tales como la longitud de una matriz:
int[] array = new int[10000];
for (int i = 0; i < array.length; ++i) {
array[i] = Random.nextInt();
}
En este caso, la aplicación ingenua sería evaluar la longitud de la matriz 10.000 veces, pero dado que la matriz de variables es Nunca asignado y la longitud de la matriz nunca va a cambiar, la evaluación se puede cambiar a:
int[] array = new int[10000];
for (int i = 0, $l = array.length; i < $l; ++i) {
array[i] = Random.nextInt();
}
Otras optimizaciones también se aplican aquí no relacionado con la elevación.
Espero que ayude.
No lo entiendo, ¿cómo terminará el ciclo si la condición es siempre cierta? –
Creo que el autor del punto de EJ es que debido a que el compilador JIT * puede * optimizar de esta manera, un programador no debería depender del valor de 'hecho' cambiando de un hilo diferente. Es posible que el compilador JIT pueda optimizar el código de este constructo y que el bucle realmente nunca termine. – ahawtho
Esta optimización puede ocurrir incluso si 'done' es una instancia o variable de clase, siempre que no sea volátil. – assylias