La descarga está en progreso. Por favor, espere

La descarga está en progreso. Por favor, espere

Tema 1: Concurrencia con Java

Presentaciones similares


Presentación del tema: "Tema 1: Concurrencia con Java"— Transcripción de la presentación:

1 Tema 1: Concurrencia con Java
Programación Concurrente y Distribuida Prácticas Tema 1: Concurrencia con Java

2 Tema 1: Concurrencia con Java
Índice: Hilos Control de hilos Planificación Coordinación de hilos Hilos demonios 2

3 Tema 1: Concurrencia con Java
Índice: Hilos Control de hilos Planificación Coordinación de hilos Hilos demonios 3

4 Tema 1: Concurrencia con Java
1. Hilos Hilo: secuencia de ejecución dentro de un proceso Todo programa Java tiene al menos un hilo: class principal { … public static void main (String args[]) . } No son necesarios los mecanismos de sincronización puesto que todos los hilos comparten el mismo espacio de memoria Dicho hilo principal puede crear nuevos hilos Java soporta mecanismos de sincronización entre hilos

5 Tema 1: Concurrencia con Java
1. Hilos Formas de crear hilos en Java: Por herencia Por delegación Creación de hilos por herencia Pasos a seguir: Creación de hilos por herencia (click): Escribir una clase que: herede de la clase Thread (click). ¡Ojo! ¡No es una clase abstracta! Redefina el método public void run(). Este método implementará la funcionalidad del hilo Crear objetos de la clase definida (click) Configurar los objetos creados (click) (cambio de prioridad, carácter de demonio…) Poner hilo en marcha: método start() (click) El método start() tiene como consecuencia que se ejecuta el método run del objeto hilo como un hilo separado, es decir, en paralelo con el hilo llamante (click) ¡OJO! Error muy habitual: llamar al método run() en lugar de start() (click). Sintácticamente (y aparentemente) funciona, pero el resultado no es más que una llamada a rutina, sin creación de hilo (click) El hilo creado puede controlar al hilo creado (click) class miHilo extends Thread { } miHilo hilo= new miHilo(...); public void run() { … } hilo.setPriority(…); hilo.setDaemon(…); hilo.start(); hilo.run(); hilo.suspend();

6 Tema 1: Concurrencia con Java
1. Hilos Creación de hilos por herencia (cont.) Objetos de clase miHilo son objetos Thread Heredan la funcionalidad de Thread: pueden usar los métodos dicha clase para controlarse a sí mismos Inconveniente: En Java: herencia simple… ¿Y si necesitamos heredar funcionalidad de otra clase?

7 Tema 1: Concurrencia con Java
1. Hilos Creación de hilos por delegación Pasos a seguir: class miHilo implements Runnable { } miHilo hilo= new miHilo(...); public void run() { … } Thread t= new Thread(hilo); Creación de hilos por delegación: Escribir una clase que: implemente la interfaz Runnable (click). Dicha interfaz sólo dispone de una operación run() que hemos de implementar (click) Crear objetos de dicha y clase (click) Como dichos objetos no son hilos, hemos de crear objetos Thread (de ahí que Thread no sea clase abstracta), pasándole objetos de la clase creada como parámetros en el constructor (click) A partir de aquí, igual que en el caso de herencia PERO: el hilo se controla con el objeto de la clase Thread (click) Para ejecutar el hilo: método start() DEL THREAD (click) Que da como resultado la ejecución del método run() como un hilo (click) t.setPriority(…); t.setDaemon(…); t.start(); Que clase sea de objetos activos no condiciona diseño Inconveniente: El hilo no puede controlarse a sí mismo

8 Tema 1: Concurrencia con Java
1. Hilos Solución: siguiente patrón de delegación class miHilo implements Runnable { public void run() { … } } private Thread hilo; … public miHilo(…) { hilo= new Thread(this); … } hilo.start(); hilo.suspend();

9 Tema 1: Concurrencia con Java
Índice: Hilos Control de hilos Planificación Coordinación de hilos Hilos demonios 9

10 Tema 1: Concurrencia con Java
2. Control de hilos Clase Thread: proporciona métodos de control Algunos de los más importantes: Método Descripción void start() Inicia la ejecución de un hilo static Thread currentThread() Proporciona referencia a hilo actual string getName() Devuelve nombre de un hilo void setName() Establece el nombre de un hilo static void sleep (long milis[, int nanos]) Suspende hilo por un tiempo determinado void suspend(); Suspende hilo hasta que se reanude por resume() void resume(); Reanuda un hilo suspendido Notas: Nombre por defecto del hilo principal: main sleep() en realidad son dos métodos distintos, en Java no hay parámetros opcionales (sobrecarga). Pueden elevar la excepción InterruptedException Suspender un hilo suspendido no tiene efecto Reanudar un hilo no suspendido no tiene efecto suspend/resume están depreciados. En su lugar, wait() y notify()

11 Tema 1: Concurrencia con Java
2. Control de hilos Método Descripción void stop(); Aborta un hilo vid interrupt() Interrumpe un hilo boolean interrupted() Comprueba si hilo ha sido interrumpido, y limpia la bandera de interrumpido boolean isInterrupted() Comprueba si hilo ha sido interrumpido void join() Hace esperar al hilo llamante hasta que termine el hilo sobre el que se llama. boolean isAlive() Comprueba si se ha llamado a start() pero aún no ha terminado el hilo. stop(): está depreciado, pues deja bloqueado los objetos que tuviese en dicho estado. En su lugar, los hilos deben terminar ordenadamente. Para abortar un hilo: O bien lo abortamos por las bravas, con stop() -> riesgo de dejar objetos bloqueados O bien lo interrumpimos ordenadamente: Método interrupt(): Levanta la bandera de interrumpido del hilo Si el hilo estaba detenido en una operación wait(), join(), sleep(), la espera acaba elevando la excepción interruptedException El hilo debe comprobar su estado mediante interrupted() o isInterrupted(). Si detecta que ha sido interrumpido, debe terminar ordenadamente. join() también puede lanzar la excepción InterruptedException();

12 Tema 1: Concurrencia con Java
Índice: Hilos Control de hilos Planificación Coordinación de hilos Hilos demonios 12

13 Tema 1: Concurrencia con Java
3. Planificación Planificación basada en prioridades estáticas Cada hilo tiene una prioridad entre Thread.MIN_PRIORITY Thread.MAX_PRIORITY Por defecto: Thread.NORM_PRIORITY No se garantiza que haya apropiación entre hilos de la misma prioridad Un hilo sólo se activa si no hay ningún hilo activo con mayor prioridad yield() nunca permitirá activarse a un hilo de menor prioridad. Simplemente fuerza la rotación entre los de la misma prioridad. Cuando un hilo crea otro, hilo creado tiene misma prioridad que hilo creador Salvo casos muy concretos de planificación a bajo nivel, nunca deberíamos crear aplicaciones que dependan de detalles de la planificación. Métodos relacionados con la planificación Descripción void setPriority() Establece prioridad de un hilo int getPriority() Obtiene la prioridad de un hilo void yield() Cede la CPU al planificador para dar la oportunidad de activarse a otros hilos

14 Tema 1: Concurrencia con Java
Índice: Hilos Control de hilos Planificación Coordinación de hilos Hilos demonios 14

15 Tema 1: Concurrencia con Java
4. Coordinación de hilos Objetos Java: similares a monitores (Hoare) monitor mimonitor { private: public: } Datos y métodos locales, variables de condición Recordatorio de monitores: los monitores garantizan la exclusión mutua en la ejecución de sus métodos. void metodo1 () { } void metodo2 () { … } Métodos públicos

16 Tema 1: Concurrencia con Java
4. Coordinación de hilos monitor mimonitor { private: public: } condition C; No olvides comentar que cada variable de condición tiene asociada una lista de procesos bloqueados en ella, y que signal() reanuda a uno cualquiera. signal() sobre una variable de condición sin procesos bloqueados no tiene efectos. Un monitor puede declarar tantas variables de condición como necesite Termina comentando brevemente el problema de la reanudación void metodo1 () { } void metodo2 () { } if (tengo_que_esperar()) wait(C); signal(C);

17 Tema 1: Concurrencia con Java
4. Coordinación de hilos Objetos java: modelo simplificado Garantizan la exclusión mutua entre métodos synchronized No hay variables de condición wait(C)  wait() Método heredado de Object Sólo en métodos declarados synchronized Puede lanzar la excepción InterruptedException signal(C)  notify() Reanuda cualquier hilo detenido en cualquier wait() del objeto Política de reanudación: preferencia al hilo reanudante Espera guardada= suspensión de un hilo o proceso en función del cumplimiento o no de una condición Problema: dificultad para implementar esperas guardadas

18 Tema 1: Concurrencia con Java
4. Coordinación de hilos class miclase { synchronized public void metodo1(…) { … while(tengo_que_esperar()) wait(); … } synchronized public void metodo2(…) { … cambiar_condicion(); notifyAll(); … } } La espera guardada se realizará con while. Por su parte, notifyAll() reanuda a todos los hilos detenidos en operaciones wait() sobre el objeto (click) El objeto inicialmente se encuentra desbloqueado (click) Un hilo entrada en el método1(). Como es synchronized, el objeto se bloquea (click) El hilo evalúa la condición y determina que debe esperar, luego llama al método wait() y se bloquea (click) El monitor se desbloquea (click) Otro hilo entra en el método2(). El monitor se vuelve a bloquear (click) Este cambia alguna condición que pueda afectar al primer hilo que entró, y hace un notifyAll(). El notifyAll() reanuda a todos los hilos que hayan dormido, incluido el primer hilo (click). De momento, no prosigue si ejecución (estrategia de reanudación). Cuando el segundo hilo sale (click), el primer hilo se reactiva, y lo primero que hace es evaluar de nuevo la condición por la que determina si debe esperar o no (click). Si el resultado de la operación fuese que debe esperar, se volvería a reanudad SI por el contrario el resultado de la comprobación es que puede proseguir, proseguiría la ejecución, saliendo del objeto (click) Al salir el segundo hilo, el objeto se desbloquea (click) Dado que wait() puede lanzar InterruptedException, o se captura dentro del método, o hay que declarar que puede lanzar dicha excepción …throws InterruptedException try { wait(); } catch(InterruptedException e) {};

19 Tema 1: Concurrencia con Java
4. Coordinación de hilos Inconvenientes de modelo Java NotifyAll(): Ineficiente, para reanudar un hilo de entre N: Reanudar N hilos Efectuar N evaluaciones Suspender N-1 hilos Notify(): soluciones complejas y difíciles de reusar y mantener synchronized debe ser explícito: dificulta la reutilización El problema de que synchronized deba ser explícito es que en el diseño de una primera versión de una aplicación podemos llegar a la conclusión de que no es necesario. Si posteriormente, en el diseño de una segunda versión, queremos reutilizar la clase, nos podemos encontrar con que en dicha versión de la aplicación SÍ que sea necesario el synchronized, y tengamos que modificar la clase original: luego no es reutilizable. Sentencia synchronize: la expresión debe dar como resultado una referencia a un objeto. Si dicho objeto está bloqueado, la sentencia esperará a que quede desbloqueado. Una vez que el objeto no está bloqueado, la sentencia lo bloquea y lo mantiene bloqueado mientras ejecuta el bloque de código asociado Atributos volatile: pueden ser actualizados de manera concurrente Buena práctica: atributos privados y modificados con exclusión mutua Sentencia synchronize (no recomendada): synchronize (expr) { … } …

20 Tema 1: Concurrencia con Java
4. Coordinación de hilos class pila { private Vector elementos= new Vector() synchronized public void apilar(Object elemento) { elementos.add(elemento); notifyAll(); } synchronized public Object desapilar() { while(elementos.isEmpty ()) try{ wait() } catch (InterruptedException e){e.printStackTrace();} Object resultado= elementos.elementAt(elementos.size()-1); elementos.removeElementAt(elementos.size()-1); return resultado; } } Ejemplo de pila tal que al intentar obtener un elemento de ella cuando está vacía, esperamos a que algún hilo inserte un elemento Nótese que, al haber una única espera guardada posible, se podría haber implementado con notify(). No obstante, implementación notifyAll() es más robusta pues ante cambios en la lógica no hay que modificar las esperas guardadas.

21 Tema 1: Concurrencia con Java
Índice: Hilos Control de hilos Planificación Coordinación de hilos Hilos demonios 21

22 Tema 1: Concurrencia con Java
5. Hilos demonios Dos tipos de hilos en Java: Hilos de usuario (por defecto) Hilos demonio La aplicación Java termina cuando terminan todos los hilos de usuario Utilidad hilos demonio: actividades en segundo plano El carácter de demonio de un hilo se le ha de asignar antes de iniciarlo (configuración) Si se intenta cambiar el carácter de demonio de un hilo una vez se ha hecho start(): IllegalThreadStateException Métodos Descripción void setDaemon (boolean d) Establece o elimina el carácter de demonio al hilo Boolean isDaemon () Obtiene el carácter de demonio del hilo

23 Cala de Macarella, Menorca. Junio 2007.


Descargar ppt "Tema 1: Concurrencia con Java"

Presentaciones similares


Anuncios Google