TEMA 5: Control de la Concurrencia en Java (API Estándar)



Documentos relacionados
EXCLUSIÓN MUTUA ENTRE HILOS. TEMA 5: Control de la Concurrencia en Java (API Estándar) Sintaxis para Bloques de Código Sincronizado

MONITORES EN JAVA. Antonio Tomeu Control de la Concurrencia en Java: API Estándar

Benemérita Universidad Autónoma del Estado de Puebla

Programación Orientada a Eventos

Benemérita Universidad Autónoma del Estado de Puebla

1 HILOS (THREADS) EN JAVA

Java y JVM: programación concurrente

Multitarea en Java. Rafa Caballero - UCM

Concurrencia en Java

Java nos ofrece la clase Thread y la interfaz Runable que permiten que varios procesos estén funcionando de forma concurrente.

Programación Concurrente en Java

PROGRAMACIÓN EN JAVA

Concurrencia. Primitivas IPC con bloqueo

Object 1. Threads en Java

Threads. La plataforma JAVA soporta programas multhreading a través del lenguaje, de librerías y del sistema de ejecución. Dos.

Java: Programación Multithread

Universidad de Cantabria

Federico Peinado

Concurrencia en Android LSUB, GYSC, URJC

class Nombre_Clase extends Nombre_SuperClase { cuerpo de la clase extendida }

Hilos en Java. Crear un Hilo. Detener un hilo. Fuente:

Modelo de Objetos Distribuidos

Tema 6. Reutilización de código. Programación Programación - Tema 6: Reutilización de código

Modulo 1 El lenguaje Java

Introducción a la Programación Orientada a Objetos

2. Estructura de un programa en Java

Programación concurrente en Java

CDI Exclusión mutua a nivel alto. conceptos

Programación Orientada a Objetos con Java

Java en 3 horas. Ampliación de Sistemas Operativos. Rodrigo Santamaría

Java RMI. Sistemas Distribuidos Rodrigo Santamaría

Cliente/Servidor en Java

Manual del Protocolo XML-RPC de Mensajería Negocios

Concurrencia: deberes. Concurrencia: Exclusión Mutua y Sincronización. Concurrencia. Dificultades con la Concurrencia

CONCURRENCIA EN JAVA. Diseño de Sistemas Operativos Avanzados 2000/2001. Pedro Pablo Gómez Martín

PROGRAMACIÓN ORIENTADA A OBJETOS (L40629) Sabino Miranda-Jiménez

11. Algunas clases estándar de Java (II)

Multitarea En Swing. Varios hilos trabajadores, también conocidos como hilos en segundo plano.

Partes de un programa en Java. A. Ejemplo de un Programa en Java /* Programa Ejemplo de Java: Muestra una Ventana Archivo: Ejemplo1.

Concurrencia en Java

RESUMEN DE CONCEPTOS BASICOS DE PROGRAMACION JAVA

ISTP CIDET COMPUTACION E INFORMATICA ARREGLOS EN JAVA

Pruebas de unidad con JUnit

Monitores Ing. Iván Medrano Valencia

SIMM: TEORÍA DE LOS S.O. I.E.S. JUAN DE LA CIERVA CURSO 2007/2008

PROGRAMACION CONCURRENTE Y DISTRIBUIDA. III.3 Concurrencia con Java: Sincronización

El lenguaje de programación Java

15. Parámetros o argumentos

Programación Orientada a Objetos en JAVA

Programación Concurrente en Java

Repaso de las características más importantes de la programación Java y su adaptación a Android

75-62 Técnicas de Programación Concurrente II 2004 java Threads

SISTEMAS OPERATIVOS AVANZADOS

Java Inicial (20 horas)

Uso de excepciones en Java

Introducción a Java LSUB. 15 de enero de 2015 GSYC

Java en 2 horas. Rodrigo Santamaría

2.2.- Paradigmas de la POO

Compiladores e Intérpretes Proyecto N 1 Sintaxis de MiniJava Segundo Cuatrimestre de 2015

Ingeniería del Software Arquitectura Física en 3 niveles

Si bien Pascal-FC no trae algunas de las características de Pascal como:

8. Sentencia return y métodos

Receta general para resolver problemas de sincronización con semáforos

Sockets en Java. La Creatividad proviene de un conflicto de ideas. Uso de Sockets

Secretos de la Programación Concurrente

Java Threads. Sistemas Distribuidos Rodrigo Santamaría

Hebras y Sincronización en Java

DISEÑO DE UNA ARQUITECTURA CLIENTE/SERVIDOR MEDIANTE OBJETOS DISTRIBUIDOS EN JAVA

Sistemas Operativos. Curso 2016 Procesos

dit UPM Tema 3: Concurrencia /ejercicios Análisis y diseño de software José A. Mañas

Curso de Java POO: Programación orientada a objetos

GESTIÓN DE EXCEPCIONES EN JAVA. CAPTURA CON BLOQUES TRY CATCH Y FINALLY. EJEMPLOS RESUELTOS. (CU00927C)

Programación orientada a objetos

TEMA 3. CLASES. EJERCICIOS

Objetivo de aprendizaje del tema

Programación en Java. Hola Jesus. Primera clase del curso de Java

Programación multihebra

Lenguajes de Programación Curso Práctica 4. Herencia. Utilización de interfaces y clases abstractas. 1. Interfaces Clases abstractas 2

Práctica 4: Java Remote Method Invocation (RMI)

Práctica sobre compartición de instancias remotas.

Mensajes. Interbloqueo

PROGRAMACION DISTRIBUIDA

1. Visión general de RMI

2) Cual modificador limita el acceso a un método de una clase pública a los miembros de la misma clase?

Arquitectura Cliente/Servidor. Invocación de Métodos Remotos RMI: Remote Method Invocation. Llamadas a Métodos Remotos

Programación Orientada a Objetos en Java

Asignatura: Administración de Bases de Datos. Pedro P. Alarcón Cavero

TEMA 6: API Java para Concurrencia de Alto Nivel

POLIMORFISMO "una interfaz, múltiples métodos".

Java: Clases Abstractas e Interfaces

FUNDAMENTOS DE PROGRAMACIÓN. SEPTIEMBRE 2005

Java RMI Remote Method Invocation. Invocación Remota de Métodos en Java

EXAMEN FINAL Metodología y Programación Orientada a Objetos. Curso Cuatrimestre de otoño. 17 de Enero de 2011

Programación Concurrente y Paralela. P(S) ; sección crítica P(S);

Programación Orientada a Objetos en Java

Programación en Java. Programación en OO

Esta extensión está obsoleta a partir de PHP 5.5.0, y será eliminada en el futuro

Estructura de datos tipo vector.

Transcripción:

TEMA 5: Control de la Concurrencia en Java (API Estándar) 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 1

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 2

HILOS EN ESPERA (BLOQUEADOS) HILO CON BLOQUEO ADQUIRIDO HILOS EN ESPERA (BLOQUEADOS) HILO CON BLOQUEO ADQUIRIDO OBJETO DE EX. MUTUA OBJETO DE EX. MUTUA 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? HILO LIBERANDO BLOQUEO 3

Sintaxis para Bloques de Código Sincronizado public metodo_x (parametros) //resto codigo del metodo; no se ejecuta en em. /*comienzo sección crítica*/ synchronized (object) Bloque de sentencias críticas //Todo el código situado entre llaves se ejecuta bajo e.m. /*fin sección crítica*/ //metodo_x 4

Semántica de Bloques de Código Sincronizado Son una implementación del concepto de región crítica. Un bloque de código está sincronizado respecto de un objeto (puede ser el mismo objeto, this) El bloque sólo se ejecuta si se obtiene el cerrojo sobre el objeto. Útil para adecuar código secuencial a un entorno concurrente 5

Política de Acceso de los Hilos en Espera CERROJO Datos en em. ESPERA POR CERROJO Código Sincronizado 6

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; 7

Acotando la Sección Crítica public class codbloqueo //usa el cerrojo del propio objeto private int numvueltas; public codbloqueo(int vueltas)numvueltas = vueltas; public void metodo() synchronized(this) //bloqueo para acceso a seccion critica for(int i=1; i<=numvueltas; i++) System.out.print(i+" "); 8

y usándola desde hilos en modo seguro public class UsacodBloqueo extends Thread 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(); 9

Output sin/con synchronized 10

Pasando el cerrojo como parámetro 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(); 11

EJERCICIOS Descargue otra vez nuestra vieja clase Cuenta_Banca.java Decida que código debe ser sincronizado, y sincronícelo. La nueva clase será Cuenta_Banca_Sync.java Escriba un programa multihebrado que use objetos de la clase anterior.llámelo UsaCuenta_Banca_Sync.java 12

Sintaxis para Métodos Sincronizados public synchronized metodo_x (parametros) //Bloque de sentencias del método //Todo el código del método se ejecuta en em. //metodo_x 13

Semántica para Métodos Sincronizados Un método synchronized fuerza la e.m entre todos los hilos que lo invocan También fuerza la e.m. con otros métodos synchronized del objeto Cualquier hilo que trate de ejecutar un método sincronizado deberá esperar si otro método sincronizado ya está en ejecución Los métodos no sincronizados pueden seguir ejecutándose concurrentemente 14

Además El cerrojo está asociado a cada instancia de una clase (objeto) Los métodos de clase (static) también pueden ser synchronized. En clases heredadas, los métodos sobreescritos pueden ser sincronizados o no, sin afectar a cómo era (y es) el método de la superclase. 15

public class MuestraBloqueoObjeto Control con Métodos Sincronizados 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..."); 16

public class UsaMuestraBloqueoObjeto implements Runnable private MuestraBloqueoObjeto p; //referencia objeto compartido private int caso; public UsaMuestraBloqueoObjeto(MuestraBloqueoObjeto o, int val) p=o; caso=val; public void run() switch(caso) case 0: p.metodoa(); break; case 1: p.metodob(); break; public static void main(string[] args) MuestraBloqueoObjeto monitor = new MuestraBloqueoObjeto(); Thread h1 = new Thread(new UsaMuestraBloqueoObjeto( monitor,0)); Thread h2 = new Thread(new UsaMuestraBloqueoObjeto( monitor,1)); h1.start(); h2.start(); 17

/*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); 18

public class ExMutua extends Thread private ObCritico SC; public ExMutua (ObCritico SecCritica) SC = SecCritica; public void run() for(;;) SC.Incremento(); System.out.println("El hilo con id. "+getname()+" ha ajustado el objeto a valor "+SC.Valor()); public static void main(string[] args) if (args.length!=2) System.err.println ("Sintaxis: java ExMutua n m"); System.exit (1); int NumHilos = Integer.valueOf(args[0]).intValue(); //num. de hilos ObCritico ContadorCritico = new ObCritico (Integer.valueOf(args[1]).intValue()); 19

ExMutua [] Hilos = new ExMutua [NumHilos]; for(int i=0; i<=numhilos-1; i++) Hilos[i] = new ExMutua (ContadorCritico); for(int i=0; i<=numhilos-1; i++) Hilos[i].start(); 20

EJERCICIOS Descargue otra vez nuestra vieja clase Cuenta_Banca.java Decida que métodos deben ser sincronizados, y sincronícelos. La nueva clase será Cuenta_Banca_Sync_Met.java Escriba un programa multihebrado que use objetos de la clase anterior.llámelo Usa_Cuenta_Banca_Sync_Met.java 21

Protocolo 1 de Control de E.M. en Java Acceder al recurso compartido donde sea necesario Definir un objeto para control de la exclusión mutua (o usar el propio objeto, this). Sincronizar el código crítico utilizando el cerrojo del objeto de control dentro de un bloque synchronized de instrucciones 22

Protocolo 2 de Control de E.M. en Java Encapsular el recurso crítico en una clase. Definir todos los métodos de la clase como no estáticos y synchronized O al menos, todos los modificadores Crear hilos que compartan una instancia de la clase creada!ojo Esto no provee sincronización 23

EJERCICIOS Modele con una clase alguna situación donde haya presencia de concurrencia y condiciones de concurso. Guárdela en Recurso.java Modifique la clase anterior protegiendo al recurso mediante el Protocolo 2 de Control de la E.M. Llame a la clase Recurso_em.java. 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. 24

La Posesión del Bloqueo es por Hilo Un método sincronizado puede invocar a otro método sincronizado sobre el mismo objeto (REENTRANCIA) Permite llamadas recursivas a métodos sincronizados Permite invocar método herededados sincronizados Descargue obj_protected.java y usa_bj_protected.java. Pruébelos: a qué conclusión llega? Incorpore ahora un método m3() recursivo dentro de obj_protected. java. Se mantiene su conclusión? 25

INTERBLOQUEO (DEADLOCK) ENTRE HILOS (1/2) Se producen cuando hay condiciones de espera de liberación de bloqueos cruzadas entre dos hilos Sólo pueden evitarse mediante un análisis cuidadoso y riguroso del uso de código sincronizado 26

INTERBLOQUEO (DEADLOCK) ENTRE HILOS (2/2) PATRÓN ESTÁNDAR public class Deadlock public static void main(string[] args) final Object region_a = new Object(); final Object region_b = new Object(); Thread Hilo_A = new Thread(new Runnable() public void run() synchronized(region_a) synchronized(region_b) calculo(); ); Thread Hilo_B = new Thread(new Runnable() public void run() synchronized(region_b) synchronized(region_a) calculo(); ); Hilo_B.start(); Hilo_A.start(); 27

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. 28

EL CONJUNTO DE ESPERA (wait-set) Conjunto de espera asociado al cerrojo e.m del objeto wait-set 29

public class adormir extends Thread public adormir() public void run() System.out.println("El hilo "+this.getname()+" dijo: mi vida activa fue breve..."); synchronized(this) trywait();catch (InterruptedException e) //cada hilo dormido sobre su propio cerrojo System.out.println(this.getName()+" dijo: pero he revivido..."); public void despertar()synchronized (this) notify(); public static void main(string[] args) adormir [] h = new adormir[10]; for(int i=0; i<10;i++) h[i]=new adormir(); h[i].start(); h[5].despertaruno(); 30

public class adormir2 extends Thread Object lock; public adormir2(object l) lock=l; public void run() System.out.println("El hilo "+this.getname()+" dijo: mi vida activa fue breve..."); synchronized(lock) trylock.wait();catch (InterruptedException e) //hilos dormidos sobre un cerrojo común System.out.println(this.getName()+" dijo: pero he revivido..."); PRUEBE AHORA adormir3.java public void despertar()synchronized (lock) lock.notify(); public void despertartodos()synchronized (lock) lock.notifyall(); public static void main(string[] args) Object cerrojo = new Object(); adormir2 [] h = new adormir2[10]; for(int i=0; i<10;i++) h[i]=new adormir2(cerrojo); h[i].start(); h[5].despertar(); h[5].despertartodos(); System.out.print("Todos terminaron..."); // observa algo anómalo? 31

Condiciones de Guarda 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. 32

Patrón de Código para Condiciones de Guarda public synchronized void m_receptor_señal() //hilo usuario se bloqueará en el metodo a espera de condición //el hilo usuario pasa al wait-set while (!condicion) trywait(); //condición de guarda catch ()(Exception e) //codigo accedido en e.m. ------------------------------------------------------------ public synchronized void m_emisor_señal() //hilo usuario enviará una señal a todos los hilos del waitset //la guarda garantiza que se despiertan los adecuados //codigo en e.m. que cambia las condiciones de estado notiyall(); 33

Protocolo de Sicronización Inter-Hilos en Java Con Espera Ocupada // Thread A public void waitformessage() while (hasmessage == false) Thread.sleep(100); // Thread B public void setmessage(string message)... hasmessage = true; 34

Protocolo de Sicronización Inter-Hilos en Java con sincronización wait-notify // 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. 35

class Sincro Patrón sincronizador int Turno; public Sincro(int t) Turno = t; public synchronized void metodo1() while(turno!= 1) try wait(); catch (Exception e) System.out.println(" Turno al hilo1..."); Turno=2; notifyall(); public synchronized void metodo2() while(turno!= 2) try wait(); catch (Exception e) System.out.println("Turno al hilo 2..."); Turno = 3; notifyall(); 36

public synchronized void metodo3() while(turno!= 3) try wait(); catch (Exception e) System.out.println("Turno al hilo 3..."); Turno = 1; notifyall(); //Sincro class Hilo1 extends Thread Sincro ref; public Hilo1(Sincro obj)ref=obj; public void run() for(;;)ref.metodo1(); //Hilo1 37

class Hilo2 extends Thread Sincro ref; public Hilo2(Sincro obj)ref=obj; public void run() for(;;)ref.metodo2(); //Hilo2 class Hilo3 extends Thread Sincro ref; public Hilo3(Sincro obj)ref=obj; public void run() for(;;)ref.metodo3(); //Hilo3 38

public class Sincronizacion public static void main (String [] args) Sincro m = new Sincro(2); new Hilo1(m).start(); new Hilo2(m).start(); new Hilo3(m).start(); System.out.println("hilos lanzados..."); //main //Sincronizacion 39

EJERCICIO Utilizando condiciones de guarda, modele un protocolo de sincronización simple Hilo B -> Hilo A que sea completamente correcto. Guarde su código en ficheros S1.java, S2.java 40