La descarga está en progreso. Por favor, espere

La descarga está en progreso. Por favor, espere

Multitareas Hilos – Procesos Locks Monitores Deadlocks Ejemplos: productor y consumidor.

Presentaciones similares


Presentación del tema: "Multitareas Hilos – Procesos Locks Monitores Deadlocks Ejemplos: productor y consumidor."— Transcripción de la presentación:

1

2 Multitareas Hilos – Procesos Locks Monitores Deadlocks Ejemplos: productor y consumidor

3 Multitasking es lo que permite que varias actividades ocurran concurrentemente en una computadora Habiltualmente se ditinguen: Multitasking basada en procesos Multitasking basada en threads (hilos)

4 Process-based multitasking Permite que los procesos (por ejemplo programas) corran concurrentemente en una computadora Thread-based multitasking Permite que partes(tareas) del mismo programa corran concurrentemente en una computadora La secuencia de código ejecutado para cada tarea define un camino(path) de ejecución independiente llamado thread(hilo) de ejecución.

5 En un ambiente que no es multi-thread (single-threaded environment), solo una tarea se ejecuta por vez. Se desperdician ciclos de CPU por ejemplo esperando por entrada de datos del usuario Multitasking permite aprovechar esos ciclos desperdiciados.

6 Algunas ventajas del multitasking basado en threads en comparación con el basado en procesos: Los threads comparten el mismo espacio de direcciones El cambio de contexto entre threads es habitualmente menos costoso que entre procesos El costo de la comunicación entre threads es relativamente bajo

7 Java soporta thread-based multitasking y proveee facilidades de alto nivel para la programación multihilos Thread safety es un término que se utiliza para describir el diseño de clases que aseguran que el estado de sus objetos es siempre consistente, aún cuando sean utilizados concurrentemente por múltiples threads

8 Comparten el proceso que corre el programa Cada thread en Java es creado y controlado por un único objeto de la clase java.lang.Thread Los threads hacen que el ambiente de ejecución sea asíncrono, permitiendo realizar distintas tareas concurrentemente

9 El entorno de ejecución distingue entre threads del usuario y deamon threads (demonios) Mientras un hilo del usuario esté vivo, la JVM no termina Los demonios ejecutan mientras haya threads del usuario activos, existen solo para servir a otros threads de usuario

10 Cuando corremos una aplicación standalone, automáticamente se crea un thread del usuario para ejecutar el método main Este thread se llama main thread Si no se crean otros threads a partir de este, entonces el programa finaliza cuando se termine de ejecutar el método main

11 Si se crean otros threads a partir del main thread, estos heredan el estado de thread de usuario. En este último caso, programa no finalizará cuando se termine el main, sino cuando finalicen todos los threads de usuario

12 Los threads en java son representados por un objeto de la clase Thread Se puede implementar un thread de alguna de las siguientes formas: Implementando la interfaz java.lang.Runnable Extendiendo la clase java.lang.Thread

13 La interfaz tiene la siguiente especificación: public interface Runnable { void run(); } Un thread que sea creado implementando esta interfaz ejecutará el código definido en el método public run()

14 Una clase implementa la interfaz Runnable y provee el método run() que va a ser ejecutado por el thread. Este objeto es un objeto Runnable. Se crea un objeto de la clase Thread pasándole un objeto Runnable como argumento al constructor. Se invoca al método start() sobre el objeto Thread. Este método retorna inmediatamente luego de que el nuevo Thread comienza a ejecutar. Es método run() del objeto Runnable es ejecutado (eventualmente) por el objeto Thread.

15

16 Una clase extiende Thread sobrescribiendo el método run() para definir el código a ejecutar por el Thread. Esta sublcase puede llamar al constructor de la clase Thread utilizando la llamada super() El método start() heredado de la clase Thread es invocado sobre el objeto que extiende Thread para que este se convierta en elegible para ser ejecutado.

17

18 Implementando Runnable: Mejor Diseño orientado a objeto Herencia simple o individual Consistencia Extendiendo Thread: Código más sencillo

19 Thread(Runnable threadTarget) static Thread currentThread() final String getName() final void setName(String name) void run() final void setDaemon(boolean flag) final boolean isDaemon()

20 Los Threads comparten el mismo espacio de direcciones, por ende, pueden compartir recursos. Hay situaciones críticas en las que se desea que solo un thread a la vez pueda acceder a un recurso compartido. Java provee mecanismos de sincronización para controlar el acceso a recursos compartidos

21 class Counter { private int count = 0; public void increment() { int n = count; count = n+1; } } ¿Que pasaría si dos threads comparten un objeto Counter c y ambos intentan ejecutar c.increment() ?

22 Un lock (o monitor) se utiliza para sincronizar el acceso a un recurso compartido. Puede asociarse a un recurso compartido. Los Threads ganan acceso al recurso cuando son los primeros en obtener el lock asociado al mismo Los locks logran exclusión mutua

23 En Java todos los objetos tienen un lock El lock de cualquier objeto puede ser utilizado para implementar exclusión mutua. Asociando un recurso compartido con un objeto Java y su lock, el objeto actúa como guardia asegurando acceso sincronizado al recurso Solo un thread a la vez podrá acceder al recurso controlado por el objeto lock

24 La palabra clave synchronized y el lock forman las bases para implementar ejecución sincronizada. Existen dos variantes: Métodos synchronized Bloques synchronized

25 Si un método de un objeto debe ser ejecutado de a un thread a la vez, entonces la declaración deberá tener la keyword synchronized Un thread que intente ejecutar este método deberá primero obtener el lock del objeto antes de poder ejecutar El lock se solicita invocando el método

26 Mientras un thread está dentro de un método synchronized, todos los demás threads que intenten ejecutar este método u otros métodos synchronized del objeto deberán esperar Esta restricción no se aplica al objeto que tenga el lock Los métodos estáticos sincronizan con el lock de la clase (independiente del lock de los objetos de la clase)

27 public Object pop() { synchronized (this) { // Synchronized block on current // object //... } También puede especificarse el lock de una clase: synchronized (.class) { }

28 Los siguientes dos segmentos de código son equivalentes: public void push(char c) { synchronized(this) { : } public synchronized void push(char c) { : }

29

30

31 Testeando threads: isAlive() – determina si el hilo está vivo. Accediendo a thread priority: getPriority() setPriority() Poniendo threads en espera: Thread.sleep() join() Thread.yield()

32 public static void main(String[] args) { Thread t = new Thread(new Runner()); t.start();... // Do stuff in parallel with the other thread for a while... // Wait here for the timer thread to finish try { t.join(); } catch (InterruptedException e) { // t came back early }... // Now continue in this thread... }

33 public class MyThread extends Thread { public void run() { while (running) { // do lots of interesting stuff try { sleep(100); } catch (InterruptedException e) { // sleep interrupted } public static void main(String args[]) { Thread t = new MyThread(); t.start(); }

34

35 Es cuando dos threads esperan cada uno por un lock de parte del otro No es detectado o evitado Puede ser evitado mediante: Decidir el orden para obtener locks Adherirse a este orden durante todo el proceso Liberar los locks en el orden inverso

36 Escenario: Considere que ud. y el chofer de un taxi son dos threads El problema: Cómo determinar cuándo está ud. en su destino? La solución: Le comunica al chofer sobre su destino y se relaja El taxista conduce y lo notifica cuando arriba a su destino

37 Los métodos utilizados son wait y notify Existen dos pooles: wait lock

38

39 Deja los datos compartidos en un estado consistente Asegura que los programas no pueden estancarse No coloca threads que esperan diferentes notificaciones en el mismo pool de wait

40 public void run() { char c; for (int i = 0; i < 200; i++) { c = (char)(Math.random() * 26 +'A'); theStack.push(c); System.out.println("Producer" + num + ": " + c); try { Thread.sleep((int)(Math.random() * 300)); } catch (InterruptedException e) { // ignore it }

41 public void run() { char c; for (int i = 0; i < 200; i++) { c = theStack.pop(); System.out.println("Consumer" + num + ": " + c); try { Thread.sleep((int)(Math.random() * 300)); } catch (InterruptedException e) { } }

42 public class SyncStack { private List buffer = new ArrayList(400); public synchronized char pop() { } public synchronized void push(char c) { }

43 public synchronized char pop() { char c; while (buffer.size() == 0) { try { this.wait(); } catch (InterruptedException e) { // ignore it... } c = ((Character)buffer.remove(buffer.size()-1)).charValue(); return c; }

44 public synchronized void push(char c) { this.notify(); Character charObj = new Character(c); buffer.addElement(charObj); }

45 A continuación veremos un ejemplo clásico: Productor/Consumidor. Tenemos 2 productores y 2 consumidores, los cuales utilizan un mismo recurso. En este ejemplo se, maneja la concurrencia al recurso compartido, el cual es producido por prodT1 y prodT2 y consumido por c1 y c2.

46 La clase Productor, implementa la interfaz Runnable. En su método run, produce todos los elementos y los coloca en la pila. Entre que coloca un elemento y otro, se ejecuta el método sleep, de manera de dormir el thread por unos instantes, de manera que otros productores tengan acceso a la pila para colocar sus elemento producidos, o bien un consumidor consuma de la misma.

47 Ahora veremos el código correspondiente a un Consumidor. Análogamente, el Consumidor también implementa la interfaz runnable. El método run, es muy similar al de la clase Productor, solo que en este caso, se consume de la pila.

48 La clase syncstack, es quien maneja la concurrencia al stack, mediante los métodos push y pop, ya que hace uso de los métodos wait() y notify(), de manera que mediante el wait, el thread espera para obtener el bloqueo y el notify, le avisa que ya termino y el recurso esta libre. A continuación veremos un ejemplo.

49 Producer2: F Consumer1: F Producer2: K Consumer2: K Producer2: T Producer1: N Producer1: V Consumer2: V Consumer1: N Producer2: V Producer2: U Consumer2: U Consumer2: V Producer1: F Consumer1: F Producer2: M Consumer2: M Consumer2: T

50 Multitareas Hilos – Procesos Locks Monitores Deadlocks Ejemplos: productor y consumidor

51 The Java Tutorial Trail de Threads


Descargar ppt "Multitareas Hilos – Procesos Locks Monitores Deadlocks Ejemplos: productor y consumidor."

Presentaciones similares


Anuncios Google