1 CONTENIDO Exclusión Mutua con código synchronized . Exclusión Mutua con métodos synchronized . Protocolos de Control de la Exclusión Mutua. Interbloqueos Sincronización: wait(), notify(),notifyAll() Condiciones de Guarda Protocolos de Sincronización Diseño de Monitores en Java BIBLIOGRAFÍA RECOMENDADA: [Göe06] Göetz et al. Java Concurrency in Practice, 2006. [Oaks04] Oaks & Wong. Java Threads. O`Reilly, 2004. [Well04] Wellings, A, Concurrent and Real Time Programming in Java. John Wiley&Sons ,2004 TEMA 5: Control de la Concurrencia en Java (API Estándar)
40
Embed
TEMA 5: Control de la Concurrencia en Java (API Estándar)
This document is posted to help you gain knowledge. Please leave a comment to let me know what you think about it! Share it to your friends and learn new things together.
Transcript
1
CONTENIDOExclusión Mutua con código synchronized. Exclusión Mutua con métodos synchronized. Protocolos de Control de la Exclusión Mutua.InterbloqueosSincronización: wait(), notify(),notifyAll()Condiciones de GuardaProtocolos de SincronizaciónDiseño de Monitores en JavaBIBLIOGRAFÍA RECOMENDADA:[Göe06] Göetz et al. Java Concurrency in Practice, 2006.[Oaks04] Oaks & Wong. Java Threads. O`Reilly, 2004.[Well04] Wellings, A, Concurrent and Real Time
Programming in Java. John Wiley&Sons ,2004
TEMA 5: Control de la Concurrencia en Java (API Estándar)
2
EXCLUSIÓN MUTUA ENTRE HILOS§ En Java la exclusión mutua se logra a nivel de
objetos. Todo objeto tiene asociado un cerrojo (lock).
§ Técnicas de Control de la E.M. en Java.§ Bloques sincronizados. El segmento de código que deba
ejecutarse en e.m. se etiqueta como synchronized. Es el equivalente a una región crítica en java.
§ Métodos sincronizados. Aquellos instancias de recursos que deban manejarse bajo e.m. se encapsulan en una clase y todos sus métodos modificadores son etiquetados con la palabra reservada synchronized.
§ Por tanto, dos o más hilos están en e.m. cuando llaman a métodos synchronized de un objeto (de exclusión mutua) o ejecutan métodos que tienen bloques de código sincronizados
CUESTIONES A DETERMINAR:• ¿Cómo establecer el bloqueo a nivel sintáctico?• ¿Cuál es la semántica del bloqueo?• ¿Qué política de acceso se da a los hilos en espera?
public class Ejemplo_Bloques_Sincronizados {private int Valor_1;private int Valor_2;protected Object Cerrojo_1 = new Object ();protected Object Cerrojo_2 = new Object ();
public int Observa_1 () { synchronized (Cerrojo_1){return (Valor_1); } } public void Modifica_1 (int dato) {synchronized (Cerrojo_1){ Valor_1 = dato; } } public void Modifica_2 (int dato) { synchronized (Cerrojo_2){ Valor_2 = dato; } } public int Observa_2 () { synchronized (Cerrojo_2){ return (Valor_2); } } public Ejemplo_Bloques_Sincronizados() { synchronized (Cerrojo_1){ synchronized (Cerrojo_2){ Valor_1 = Valor_2 = 1; } } }}
codBloqueo cerrojo; //referencia a objeto compartido
public UsacodBloqueo(codBloqueo l) {cerrojo = l;} public void run() { cerrojo.metodo(); //llamada a metodo que tiene codigo sincronizado }
public static void main(String[] args) { codBloqueo aux = new codBloqueo(200); UsacodBloqueo h1 = new UsacodBloqueo(aux); UsacodBloqueo h2 = new UsacodBloqueo(aux); h2.start(); h1.start(); }}
public class MuestraBloqueo implements Runnable { private Object o; public MuestraBloqueo(Object p) //cerrojo como parámetro del constructor {o = p;} public void run() { synchronized(o)//primer hilo que llega adquiere cerrojo { for(int i=1;i<100;i++){ //no habra entrelazado de impresiones System.out.println("Iteracion "+i+" del hilo "+this.toString()); for(int j=1;j<100;j++); //retraso para visualizar } } } public static void main(String[] args) { Object lock = new Object(); //objeto para cerrojo compartido por los hilos Thread h1 = new Thread(new MuestraBloqueo(lock), "hilo 1"); Thread h2 = new Thread(new MuestraBloqueo(lock), "hilo 2"); h1.setPriority(Thread.MIN_PRIORITY); h2.setPriority(Thread.MAX_PRIORITY); h1.start(); h2.start(); }}
public synchronized void metodoA() { for(int i=1;i<100;i++){ System.out.println("Iteracion "+i+" del metodo A "); for(int j=1;j<100;j++);//retraso para visualizar } System.out.println("metodo A liberando cerrojo..."); }
public synchronized void metodoB() { for(int i=1;i<100;i++){ System.out.println("Iteracion "+i+" del metodo B "); for(int j=1;j<100;j++); } System.out.println("metodo B liberando cerrojo..."); }
/*Ejemplo de Exclusion Mutua entre Hilos *@author Antonio J. Tomeu *Varios hilos concurrentes modifican contador protegido bajo e.m. *El metodo que incrementa al contador es synchronized *Crea un array de hilos que incrementan bajo e.m. el contador *Sintaxis de uso: java ExMutua n m donde: *n es el numero de hilos concurrentes *m es el valor inicial del contador*/
class ObCritico{ private int Dato; //Contiene el objeto critico
public ObCritico (int VInicial) //el constructor {Dato = VInicial;}
public synchronized void Incremento() //e ejecutar bajo e.m. {Dato++;}
public int Valor () //hace una lectura. No necesita e.m. {return (Dato);}}
n Modele con una clase alguna situación donde haya presencia de concurrencia y condiciones de concurso. Guárdela en Recurso.java
n Modifique la clase anterior protegiendo al recurso mediante el Protocolo 2 de Control de la E.M. Llame a la clase Recurso_em.java.
n Escriba ahora un programa llamado Prueba_Recurso_em.java que haga uso de la clase anterior. Debe crear varios hilos concurrentes mediante implementación de la interfaz Runnable.
SINCRONIZACIÓN ENTRE HILOS§ En Java la sincronización entre hilos se logra con los métodos wait,
notify y notifyAll (Clase Object)
§ Deben ser utilizados únicamente dentro de métodos o código de tipo synchronized.
§ Cuando un hilo llama a un método que hace wait las siguientes acciones son ejecutadas atómicamente:1. Hilo llamante suspendido y bloqueado.2. Exclusión mutua sobre el objeto liberada.3. Hilo colocado en una cola única (el wait-set) de espera asociada al objeto.
§ Cuando un hilo llama a un método que hace notify, uno de los hilos bloqueados en la cola pasa a listo. Java no especifica cuál. Depende de la implementación (JVM)Si se llama al método notifyAll todos los hilos de dicha cola son desbloqueados y pasan a listos. Accederá al objeto aquél que sea planificado.
§ Si el wait-set está vacío, notify y notifyAll no tienen efecto.
§ No se puede escribir código de hilos asumiendo que un hilo concreto recibirá la notificación.
§ Diferentes hilos pueden estar bloqueados sobre un mismo objeto a la espera de diferentes condiciones
§ Dado que notifyAll() los despierta a todos de forma incondicional, es posible que reactive hilo para los cuales no se cumple aún la condición de espera.
§ Solución: siempre que el hilo usuario invoca a wait(), lo primero al despertar es volver a comprobar su condición particular, volviendo al bloqueo si ésta aún no se cumple.
// Thread A public synchronized void waitForMessage() {try {
wait(); } catch (InterruptedException ex) { } }
// Thread B public synchronized void setMessage(String message) { ...notify();
OJO: No es perfecto. La señal puede perderse (y se pierde) si nadie está esperándola.
SOLUCIÓN: Utilizar condiciones. A sólo se bloqueará si al comprobar una condición ésta es falsa, y B se asegurará de hacer que la condición sea verdadera antes de notificar.
Protocolo de Sicronización Inter-Hilos en Javacon sincronización wait-notify