Práctica 02 - ProgProcesosYServicios/Practicas-2 GitHub Wiki

Práctica 2.2: Comportamiento dela memoria: atributos volatile

La especificación de la máquina virtual de Java es el documento que formaliza las características que deben cumplir todas las implementaciones válidas de la J VM. Especifica no sólo el formato de los . class, el modo en el que se inicializan, o las instrucciones “de ensamblador” de la máquina, sino también el comportamiento de la memoria.

Pensando, entre otras cosas, en que la JVM se pueda implementar en un sistema distribuido diferencian entre “memoria principal” y “memoria local” de una hebra. En sistemas simétricos con memoria compartida, parece que ambas deberían ser la misma; pero como programadores de Java no podemos tener la certeza de que sea así, ni siquiera en ese caso.

Cuando se realiza un programa secuencial, este hecho no es importante; pero cuando estamos utilizando múltiples hebras compartiendo recursos sí lo es. En concreto, la especificación de la máquina virtual nos dice:

  • Múltiples actualizaciones de la misma variable por parte de una hebra serán vistas en el mismo orden por otras hebras. Pero no se garantiza que se vean todas.

  • La actualización de varias variables en una hebra no tienen por qué verse en el mismo orden en otras hebras, salvo que las variables se declaren volatile.

  • La actualización de una variable “larga” (long o double) no debe considerarse atómica; la hebra que escribe podría ser expropiada cuando haya cambiado sólo una de las mitades (32 de los 64 bits).

Considera la clase siguiente:


public class Clase {
	
	static int i = 0;
	
	
	static void cambia(){
		i = 3;
		i = 4;
	}
	static int calcula(){
		int result = i;
		result += 2 * i;
		return result;
	}

} // class Clase

Si una hebra llama a cambia() y otra a calcula(), ¿qué valores podría recibir como repuesta esta última?

(0,0), (0,3), (0,4), (3,3), (3,4), (4,4)

considera ahora el siguiente código:

public class Clase {

	static int x = 0, y = 0;	
	
	static void cambia(){
		x = 3;
		y = 4;
	}
	static int calcula(){
		int result = y;
		result += x;
		return result;
	}

} // class Clase

¿Qué valores podría obtener la hebra que llama a calcula() si otra ha llamado a cambia()?¿Y si declaráramos volatile los atributos?

(0,0), (3,0), (0,4), (3,4)

Si las declaramos como volatil la pareja (0,4) no se puede dar.