[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Java Memory Model



Hola,

En la web de Sun se puede consultar (y descargar) la última edición del libro 
"Java Programming Language Specification", en su tercera edición [1].

En su capítulo 17 se describe el modelo de ejecución concurrente específico de 
Java, lo que denominan "Java Memory Model".

He estado leyendo ese capítulo, y tengo que reconocer que me ha sorprendido. 
De hecho, la concurrencia en Java se basa en permitir cierta libertad y 
flexibilidad de forma que se consiga que los compiladores lleven a cabo 
optimizaciones de diversa índole, para mejorar en lo posible el rendimiento 
del código para cada plataforma. Algunas de esas optimizaciones son tan 
llamativas como cambiar el orden de las lecturas y escrituras de variables.
Si alguna vez os habéis encontrado con un bug que sólo se da en ocasiones 
esporádicas, y no conseguís realmente inferir sus causas revisando el código, 
es factible que sea un problema de concurrencia, *dependiente del compilador 
que hayáis usado*.
En principio, las conclusiones que obtengo de la especificación son:
-El compilador tiene libertad para reordenar las lecturas y escrituras de 
variables, aunque debe respetar unas relaciones de orden, algunas de ellas 
sólo necesarias, no suficientes.
-En una ejecución secuencial, tal ordenación no tiene efectos visibles.
-En una ejecución concurrente, sin embargo, sí los puede tener. De hecho, me 
resulta difícil asegurar, sin revisarlo de nuevo, que el código que he 
tratado de hacer thread-safe lo sea en realidad, según el JMM.
-Hay multitud de detalles que hay que tener en cuenta, como el uso de las 
variables final (que tienen mucho que decir en lo referente a la ejecución 
concurrente); el hecho de que el "heap" es zona de memoria compartida por 
todas las hebras, mientras que los parámetros locales a los métodos son 
inherentemente thread-local; la importancia de las variables "volatile"...
-La libertad de elección de un compilador u otro queda muy condicionada a 
pruebas exhaustivas del código en un entorno de ejecución concurrente.

Os invito de verdad a que echéis un vistazo, si no lo habéis hecho ya, a los 
ejemplos que se describen en ese capítulo, porque no tienen desperdicio. Como 
entrada, el de la última página no es un mal ejemplo.

Igual habría que pensar en una herramienta que, a partir de postcondiciones 
concurrentes declaradas en el Javadoc, crease pruebas que permitieran 
comprobar si el código las respeta o no. Aunque por otro lado, a nivel de 
método es una granularidad demasiado gruesa...

Un saludo,
Jose.

[1] http://java.sun.com/docs/books/jls/