¿Cómo funciona la sincronización de hilos en una sección crítica de un programa en Java?

¿Cómo funciona la sincronización?
Estoy haciendo una aplicación con varios hilos, que estén sincronizados para no poder entrar en una sección critica simultáneamente.
Lo hago extendiendo la clase Thread.
Tengo los siguientes métodos:
public synchronized void met ()
{ i
nt i; for (i=0; i<20; i++)
System.out.println (name + " " + i);
}
public void run ()
{ met (); }
Luego en el main creo las instancias de los objetos y llamo al método start de los mismos.
Supuestamente la salida debería ser primero las 20 iteraciones de un objeto, luego las de otro... Así para cada uno, pues el método met es sincronizado.
PERO ME SALEN MEZCLADAS hilo1 4 hilo1 5 hilo2 3 hilo1 6
¿Estoy haciendo algo mal?
¿La sincronización no sirve para eso?
Respuesta
1
Entiendo que el problema que tienes es debido al planificado de thread's de java, me explico, existen dos tipos de planificadores de thread's:
- Planificado pre-emtivo (el proceso que se está ejecutando, no abandonará el procesador hasta que acabe)
- Round robin (todo proceso tiene un tiempo de ejecución, quantum, pre-establecido, después del cual, abandona el procesador)
Entiendo que lo que a ti te ocurre, es que se entremezclan las ejecuciones de los threads, debido a la política del planificado (que será round robin).
Para evitar esto, y que realmente tenga sentido nuestra sección crítica, deberemos poner un flag o variable, de tal modo que cuando un thread se ejecute ponga el flag a true, de tal modo que si el otro thread detecta que el flag ya ha sido puesto a true, espere a que el otro thread termine su ejecución, restaurando el valor del flag.
Te ilustro el caso, con el ejemplo típico del productor/consumidor:
class PyC {
private int contents;
private boolean available = false; //flag
public synchronized int get() {
while (available == false) {
try {
wait();
} catch (InterruptedException e) {
}
}
available = false;
notify();
return contents;
}
public synchronized void put(int value) {
while (available == true) {
try {
wait(); //el thread tiene que esperar
} catch (InterruptedException e) {
}
}
contents = value;
available = true;
notify();
}
}
En tú caso sería lo mismo, pero teniendo únicamente un método sincronizado.
A continuación te pongo el código para tú caso, sería algo así:
available = false; //flag
public synchronized void met ()
{
while (available == false){
try{
wait();
} catch (InterruptedException e) {
}//del catch
}//del while
available = false;
int i; for (i=0; i<20; i++){
System.out.println (name + " " + i);
}
available = true;
}
public void run ()
{ met (); }
Al empleo de un flag, para el uso compartido de un objeto, se le llama Monitor, de tal forma que tenemos un modo de monitorizar el estado de un objeto, para el tratamiento de las secciones críticas.

Añade tu respuesta

Haz clic para o

Más respuestas relacionadas