Tuve una pequeña discusión con mi maestro sobre la palabra clave volatile en Java. ¿Es correcto decir que cuando una variable se declara como volatile :
El valor de esta variable nunca se almacenará en caché localmente: todas las lecturas y escrituras irán directamente a la "memoria principal".
La opinión de mis profesores es que:
La palabra clave
volatileno promete que el valor de la variable se guardará en la memoria principal.
¿Alguien puede resolver nuestro conflicto? ¡Gracias!
Para conocer el significado exacto de palabras clave como volatile , consulte la Especificación del lenguaje Java para ver el significado oficial.
JLS párrafo 8.3.1.4 explica lo que significa volatile :
Un campo puede declararse volátil, en cuyo caso el modelo de memoria de Java garantiza que todos los subprocesos vean un valor coherente para la variable (§17.4).
El párrafo 17.4 explica el modelo de memoria de Java. El modelo de memoria le brinda ciertas garantías sobre lo que sucede con los datos después de cada declaración en un programa.
Si estudia eso cuidadosamente, encontrará que volatile significa que si escribe en una variable volátil, tiene la garantía de que otros subprocesos verán lo que se escribió. No se especifica deliberadamente cómo se implementa esto en la práctica. Puede implementarse forzando una escritura en la memoria principal, pero los implementadores de JVM son libres de elegir un mecanismo diferente, posiblemente más eficiente.
Entonces, estrictamente hablando, tu maestro tiene razón. No significa necesariamente que el valor se escriba en la memoria principal; aunque en la práctica, este podría ser el caso, pero depende de la implementación particular de JVM.
Lo que hace volatile es ignorar todos los cachés de CPU locales; o de manera equivalente, actualice la línea de caché que contiene esa variable volatile que se actualizará desde la memoria principal. Por lo tanto, como sugiere la documentación, se asegura de que todas las lecturas se lean directamente desde la memoria principal y todas las escrituras vayan directamente a la memoria principal.
Además de esto, volatile también cuentan con la garantía de funcionamiento atómico. Se asegura de que la variable precedida por esta palabra clave se lea o escriba en su totalidad como si fuera una sola instrucción. (por el contrario, no se preocupará de que un entero largo de 64 bits escrito por 2 subprocesos termine con los primeros 32 bits de un subproceso y los segundos 32 bits de otro subproceso). Por lo tanto, en alguna situación determinada, por ejemplo, si usa volatile en un entero largo de 64 bits en una máquina de 32 bits, es posible que la JVM deba hacer algo más que una instrucción "volátil". Algunas documentaciones más están en https://blogs.oracle.com/dave/entry/java_memory_model_concerns_on .
A su pregunta específica.
volatile en Java, se asegura de que el valor de la variable sea de la memoria principal.volatile en Java, se asegura de que el valor de la variable se escriba en la memoria principal.Habiendo dicho lo anterior, esto es desde un punto de vista "lógico". En realidad, las CPU modernas emplean una política de almacenamiento en caché compleja y, a veces, pueden garantizar que lo anterior sea cierto sin tener que escribir en la memoria principal. Sin embargo, solo lo hace al darse cuenta de que se puede lograr absolutamente el mismo efecto como un paso de optimización del rendimiento. Pero creo que esto está más allá del alcance de la discusión.
Solo citaré dos párrafos de docs
Un campo puede declararse volátil, en cuyo caso el modelo de memoria de Java garantiza que todos los subprocesos vean un valor coherente para la variable (§17.4).
El modelo de memoria describe los posibles comportamientos de un programa. Una implementación es libre de producir cualquier código que desee, siempre que todas las ejecuciones resultantes de un programa produzcan un resultado que el modelo de memoria pueda predecir.
Esto proporciona una gran libertad para que el implementador realice una gran cantidad de transformaciones de código, incluida la reordenación de acciones y la eliminación de la sincronización innecesaria.
Ahora, si se refiere a la mayoría de los tutoriales sobre votatile keyword in java , la mayoría de ellos sugerirá lo mismo que sugirió, es decir, el valor de esta variable nunca se almacenará en caché localmente: todas las lecturas y escrituras irán directamente a la "memoria principal" .
Pero los documentos no garantizan nada al respecto. Aunque nunca lo niega así. Simplemente dice que este es el posible comportamiento .
Así que diría que tu profesor tiene razón. Según los documentos (y no la mayoría de los tutoriales que no sean documentos), la palabra clave volátil definitivamente no promete que el valor de la variable se guardará en la memoria principal.
Sin embargo, esto no lo equivoca, todo depende de la implementación de JVM.