16

Click here to load reader

Tema 5 monitores

  • Upload
    atomeu

  • View
    5.550

  • Download
    0

Embed Size (px)

Citation preview

Page 1: Tema 5 monitores

1

Ø Un monitor es un objeto que implementa acceso bajo e.m. a todos sus métodos, y provee sincronización

Ø En Java, son objetos de una clase cuyos métodos públicos son todos synchronized

Ø Un objeto con métodos synchronized proporciona un cerrojo único que permite implantar monitores con comodidad y e.m. bajo control

Ø Los métodos wait(), notify(), notifyAll() permiten sincronizar los accesos al monitor, de acuerdo a la semántica de los mismos ya conocida.

MONITORES EN JAVA

© Antonio Tomeu Control de la Concurrencia en Java: API Estándar

Page 2: Tema 5 monitores

2

class Monitor { //definir aquí datos protegidos por el monitor public Monitor(){…} //constructor

public synchronized tipo1 metodo1() throws InterruptedException{

… notifyAll(); … while(!condicion1) wait(); } public synchronized tipo2 metodo2()

throws InterruptedException{ … notifyAll(); … while(!condicion1) wait(); }}

ESTUCTURA SINTÁCTICA DE UN MONITOR EN JAVA

© Antonio Tomeu Control de la Concurrencia en Java: API Estándar

Page 3: Tema 5 monitores

3

Ø Cuando un método synchronized del monitor llama a wait() libera la e.m. sobre el monitor y encola al hilo que llamó al método en el wait-set.

Ø Cuando otro método del monitor hace notify(), un hilo del wait-set (Java no especifica cuál) pasará a la cola de hilos que esperan el cerrojo y se reanudará cuando sea planificado.

Ø Cuando otro método del monitor hace notifyAll(), todos los hilos del wait-set pasarán a la cola de hilos que esperan el cerrojo y se reanudarán cuando sean planificados.

SEMÁNTICA DEL MONITOR EN JAVA

© Antonio Tomeu Control de la Concurrencia en Java: API Estándar

Page 4: Tema 5 monitores

4

Ø El monitor Java tiene no tiene variables de condición, solo una cola de bloqueo de espera implícita

Ø La política de señalización es señalar y seguir (SC)Ø El método (hilo) señalador sigue su ejecuciónØ El hilo(s) señalado(s) pasan del wait-set a la

cola de procesos que esperan el cerrojoØ Para dormir a un hilo a la espera de una condición

usamos el método wait (dentro de un método synchronized)

Ø Es menos fino que una variable de condiciónØ El conjunto de espera para wait es único (wait-set)

© Antonio Tomeu Control de la Concurrencia en Java: API Estándar

Page 5: Tema 5 monitores

5

Ø No es posible programar a los hilos suponiendo que recibirán la señalización cuando la necesiten.

Ø Al no existir variables de condición, sino una única variable implícita, es conveniente utilizar notifyAll para que todos los procesos comprueben la condición que los bloqueó:

Ø No es posible señalizar a un hilo en especial. Por tanto:Ø Es aconsejable bloquear a los hilos en el wait-set con

una condición de guarda en conjunción con notifyAll().Ø while (!condicion) try {wait();} catch (InterruptedException e) {return;}

Ø Todos serán despertados, comprobarán la condición y volverán a bloquearse excepto los que la encuentren verdadera (que pasan a espera del cerrojo sobre el monitor).

Ø No es aconsejable comprobar la condición de guarda con ifØ Los campos protegidos por el monitor suelen declararse

private

MONITORES EN JAVA: PECULIARIDADES

© Antonio Tomeu Control de la Concurrencia en Java: API Estándar

Page 6: Tema 5 monitores

6

Técnica de Diseño de Monitores en Java

1. Decidir qué datos encapsular en el monitor.2. Construir un monitor teórico, utilizando tantas variables

de condición como sean necesarias.3. Usar señalización SC en el monitor teórico.4. Implementar en java

1. Escribir un método synchronized por cada procedimiento.2. Hacer los datos encapsulados private.3. Sustituir cada wait(variable_condición) por una

condición de guarda while(!condicion) try{wait()}…4. Sustituir cada send(variable de condición) por una

llamada a notifyAll()5. Escribir el código de inicialización del monitor en el

constructor del mismo

© Antonio Tomeu Control de la Concurrencia en Java: API Estándar

Page 7: Tema 5 monitores

7

/**Ejemplo de Monitor sencillo. Encapsula una variable protegida por *la abstraccion y posee una interfaz de dos metodos para *incrementarla y decrementarla y un tercero para conocer el valor *del recurso protegido.

*@author Antonio Tomeu*/ class Monitor{

private static int Dato; //recurso protegidopublic Monitor(int VInic){Dato=VInic;}

public synchronized void INC(){

while(!(Dato<=0))try{System.out.println("Hilo Sumador bloqueado"); wait(); } catch (InterruptedException e){}

Dato++;notifyAll();

}

© Antonio Tomeu Control de la Concurrencia en Java: API Estándar

Page 8: Tema 5 monitores

8

public synchronized void DEC(){

while(!(Dato>0)) try{System.out.println("Hilo Restador bloqueado");

wait(); } catch (InterruptedException e){}Dato--;notifyAll();

}public synchronized String toString(){return(new Integer(Dato).toString());}

}

class HiloSumadorextends Thread

{private Monitor Data;public HiloSumador(Monitor Ref){Data=Ref;}public void run(){

for(;;)Data.INC();}

}© Antonio Tomeu Control de la Concurrencia en Java: API Estándar

Page 9: Tema 5 monitores

9

class HiloRestadorextends Thread

{private Monitor Data;public HiloRestador(Monitor Ref){Data=Ref;}public void run(){

for(;;)Data.DEC();}

}

public class MonitorSimple{

public static void main(String[] args){

Monitor O = new Monitor(1000);new HiloSumador(O).start();new HiloRestador(O).start();new HiloRestador(O).start();new HiloRestador(O).start();

for(;;)System.out.println(O.toString());}

} © Antonio Tomeu Control de la Concurrencia en Java: API Estándar

Page 10: Tema 5 monitores

10

/**@author Antonio Tomeu */ public class Buffer { private int numSlots = 0; private double[] buffer = null; private int putIn = 0, takeOut = 0; private int cont = 0; public Buffer(int numSlots) { this.numSlots = numSlots; buffer = new double[numSlots]; }

MONITOR PRODUCTOR-CONSUMIDOR

© Antonio Tomeu Control de la Concurrencia en Java: API Estándar

Page 11: Tema 5 monitores

11

public synchronized void insertar (double valor) { while (cont == numSlots) //condición de buffer try { lleno wait(); } catch (InterruptedException e) { System.err.println("wait interrumpido"); }

buffer[putIn] = valor; putIn = (putIn + 1) % numSlots; cont++; notifyAll(); //inserción en e.m. }

© Antonio Tomeu Control de la Concurrencia en Java: API Estándar

Page 12: Tema 5 monitores

12

public synchronized double extraer () { double valor; while (cont == 0) //condición de buffer vacío try { wait(); } catch (InterruptedException e) { System.err.println("wait interrumpido"); } valor = buffer[takeOut]; takeOut = (takeOut + 1) % numSlots; cont--; notifyAll(); return valor; //extracción en e.m. } }//Buffer

© Antonio Tomeu Control de la Concurrencia en Java: API Estándar

Page 13: Tema 5 monitores

13

class Productor implements Runnable { private Buffer bb = null; public Productor (Buffer bb) {this.bb = bb;} public void run() { double item = 0.0; while (true) { bb.insertar (++item); System.out.println("Produciendo " + item); } }//run}//Productor

Diseño de Hilos sobre el Monitor

© Antonio Tomeu Control de la Concurrencia en Java: API Estándar

Page 14: Tema 5 monitores

14

class Consumidor implements Runnable { private Buffer bb = null; public Consumidor (Buffer bb) {this.bb = bb; } public void run() { double item; while (true) { item = bb.extraer (); System.out.println("Consumiendo " + item); } }//run }//Consumidor

© Antonio Tomeu Control de la Concurrencia en Java: API Estándar

Page 15: Tema 5 monitores

15

public class Prueba_Prod_Con { public static void main (String [] args) { int ranuras = 10; Buffer monitor = new Buffer (ranuras); new Thread(new Productor(monitor)).start(); new Thread(new Consumidor(monitor)).start(); }//main}//Prueba_Prod_Con

© Antonio Tomeu Control de la Concurrencia en Java: API Estándar

Page 16: Tema 5 monitores

16

n Aumente el número de lectores y escritores, y verifique la sincronización

n Diseñe un monitor en java que modele la abstracción semáforo, dótelo de métodos wait y signal, y guárdelo en semaforo.java

n Escriba ahora un protocolo de e.m. con una instancia de la clase anterior, y guárdelo en Usa_semaf.java que utilice la cuenta encapulada en el monitor

n Construya un monitor que dé solución al problema de los filósofos

EJERCICIO

© Antonio Tomeu Control de la Concurrencia en Java: API Estándar