[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Java Memory Model
- To: mindfood@xxxxxxxxxxxxxxx
- Subject: Java Memory Model
- From: Jose San Leandro <jose.sanleandro@xxxxxxxxxxxx>
- Date: Fri, 27 May 2005 09:43:11 +0200
- Delivered-to: mailing list mindfood@orange-soft.com
- Delivered-to: moderator for mindfood@orange-soft.com
- Mailing-list: contact mindfood-help@orange-soft.com; run by ezmlm
- Organization: Ventura24
- User-agent: KMail/1.8
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/