La descarga está en progreso. Por favor, espere

La descarga está en progreso. Por favor, espere

TEMA 2. Programación Concurrente

Presentaciones similares


Presentación del tema: "TEMA 2. Programación Concurrente"— Transcripción de la presentación:

1 TEMA 2. Programación Concurrente
Introducción Primer ejemplo y estado de los threads Grupos de Threads y planificación interna. Concurrencia. El problema del productor/consumidor El problema de los lectores y escritores. Aplicaciones.

2 Bibliografía Bishop,J. Java. Fundamentos de programación. Capítulo 13.
Bobadilla, J. y otros. Comunicaciones y Bases de Datos en Java. Capítulo 2. Doug Lea. Programación Concurrente en Java.

3 1 . Introducción La habilidad de un programa individual de hacer más de una cosa a la vez es implementado normalmente a través de lo que se conoce como threads (hilos, hebras o procesos java). Una hebra puede definirse de forma intuitiva como un trozo de ejecución del programa que tienen lugar simultáneamente con, e independientemente, de cualquier otra cosa que se esté ejecutando.

4 Se debe tener mucho cuidado con el abrazo mortal (deadlock).
1 . Introducción Intuitivamente debemos distinguir entre la multitarea de un sistema operativo y la programación en threads. Los entornos que permiten el uso de threads permiten la exclusión mutua en recursos compartidos mediante la sincronización. Se debe tener mucho cuidado con el abrazo mortal (deadlock).

5 1 . Introducción La elección exacta de qué parte del sistema debe ser sincronizada es la parte más delicada de la programación concurrente. La JVM no es un proceso ejecutable, es una especificación. Un programa que implementa la especificación es lo que se conoce como java runtime (JRE). Las aplicaciones Java y los applets son threads por sí. La forma en que se implementa threads en Java es mediante la clase java.lang.Thread que implementa la interface runnable.

6 public class Printer extends Thread { public void run() {
2. Primer ejemplo public class Printer extends Thread { public void run() { for (int b = -128; b < 128; b++) { System.out.println(b); }}}

7 public class Printer implements Runnable { public void run() {
2 . Primer ejemplo public class Printer implements Runnable { public void run() { for (int b = -128; b < 128; b++) { System.out.println(b); }}}

8 2. Primer ejemplo En el primer caso se crearía una instancia de la forma habitual Printer p=new Printer(); y en el segundo: Thread proc =new Thread(p); Aunque el objeto de tipo Runnable contiene la lógica principal, la clase Thread es la única que encapsula el mecanismo para lanzar y controlar el thread. Para lanzar a ejecución un hilo debemos utilizar el método start(), que invocará al método run().

9 2 . Primer ejemplo Estados Esquemáticamente, la vida de un Thread se corresponde con el siguiente gráfico: NEW DEAD RUNNABLE NOT RUNNABLE

10 2 . Primer ejemplo Para cada uno de los casos:
public class ThreadTest { public static void main(String args[]) { Printer bp = new Printer(); bp.start(); for (int i = -128; i < 128; i++) { System.out.println("Metodo main: " + i); } }}

11 2 . Primer ejemplo Para cada uno de los casos:
public class ThreadTest { public static void main(String args[]) { Printer r= new Printer(); Thread bp = new Thread(r); bp.start(); for (int i = -128; i < 128; i++) { System.out.println("Metodo main: " + i); }}}

12 2 . Primer ejemplo Es conveniente darle a cada thread un nombre distinto. Para identificarlos se le suele pasar un String al constructor (sino, el sistema lo nombra internamente como Thread-N) que me sirva para identificarlo. public class MultiThreadTest { public static void main(String args[]) { Printer bp1 = new Printer("bp1"); Printer bp2 = new Printer("bp2"); Printer bp3 = new Printer("bp3"); bp1.start(); bp2.start(); bp3.start(); }

13 public class Printer extends Thread { public Printer(String s) {
2 . Primer ejemplo public class Printer extends Thread { public Printer(String s) { super(s); } public void run() { for (int b = -128; b < 128; b++) { System.out.println(getName() + ": " + b); }}}

14 3 . Planificación interna
A veces es conveniente darle más importancia a unos sobre otros public class TestPrioridad { public static void main(String args[]) { Printer bp1 = new Printer("Pepe"); Printer bp2 = new Printer("Maria"); Printer bp3 = new Printer("Juan"); bp1.setPriority(Thread.MIN_PRIORITY); bp2.setPriority(Thread.NORM_PRIORITY); bp3.setPriority(Thread.MAX_PRIORITY); bp1.start(); bp2.start(); bp3.start(); }}

15 3 . Planificación interna
La Java Virtual Machine utiliza un algoritmo reentrante, pero no round-robin. A veces interesa ralentizar un thread, dormirlo. try {sleep(1000);} catch (InterruptedException e) {}

16 4 . Concurrencia Hay muchas veces que los threads deben de comunicarse y sincronizarse. La comunicación permite que la ejecución de hilo influya en la ejecución de otro mediante el intercambio de datos. La sincronización permite establecer restricciones sobre el orden de ejecución entre diferentes hilos.

17 4 . Concurrencia La sincronización limita el acceso a un método u objeto de un thread cada vez. Para sincronizar los objetos o métodos se añade la palabra reservada synchronized, después del modificador de acceso. De esta forma se accede en exclusión mutua al objeto o al método. synchronized void metodo(); En Java se sigue el mismo mecanismo que describió Hoare, pero con una variación: se sincronizan los métodos mediante una palabra reservada, no mediante el uso explícito de un monitor. Todo objeto en Java tiene asociado un monitor implícito.

18 public synchronized void print() {
4 . Concurrencia public class Printer { static int i = 0; public synchronized void print() { for (i = 1; i <= 10; i++) { System.out.println(i); }}}

19 4 . Concurrencia Debemos tener alguna forma que bajo algunas condiciones nos permita bloquear el Thread hasta que el recurso que necesite se encuentre libre. La forma de hacer esto es mediante el uso de las instrucciones wait() y notify(). try { // ejecutar el código wait(); } catch (InterruptedException e){ } Tanto el wait() como el notify() se deben invocar desde métodos synchronized, ya que sólo se pueden invocar si el thread en cuestión posee el monitor del objeto, cosa que sólo ocurre si accede a un método synchronized. Hay que tener en cuenta que al hacer un wait() se liberan todos los recursos, incluyendo el monitor. En cuanto al notify(), puede ocurrir que cuando es invocado haya en la cola cero o más threads esperando.

20 Almacen 5 . Problema del productor consumidor class Almacen {
private int seq; private boolean disponible = false; public synchronized int consumir() { while (disponible == false) { try { wait(); } catch (InterruptedException e) {} disponible = false; notify(); return seq;

21 Almacen 5 . Problema del productor consumidor
public synchronized void producir(int value) { while (disponible == true) { try { wait();} catch (InterruptedException e){} } seq = value; disponible = true; notify();

22 Productor 5 . Problema del productor consumidor
class Productor extends Thread { private Almacen almacen; private int numero; public Productor(Almacen c, int numero) { almacen = c; this.numero = numero;} public void run() { for (int i = 0; i <= 10; i++) { almacen.producir(i); System.out.println("Productor #" + this.numero + " pon: " + i); try { sleep((int)(Math.random() * 100));} catch (InterruptedException e) {}}}}

23 Consumidor 5 . Problema del productor consumidor
class Consumidor extends Thread { private Almacen almacen; private int numero; public Consumidor(Almacen c, int numero) { almacen = c; this.numero = numero; } public void run() { int value = 0; for (int i = 0; i <= 10; i++) { value = almacen.consumir(); System.out.println("Consumidor #" + this.numero + " cons: " +value);}}}

24 Principal 5 . Problema del productor consumidor class ProdConTest {
public static void main(String args[]) { Almacen c = new Almacen(); Productor p1 = new Productor(c, 1); Consumidor c1 = new Consumidor(c, 1); p1.start(); c1.start(); }

25 6 . Problema de lectores y escritores
Lectores/ Escritores “El problema de los lectores y escritores es una abstracción del acceso a una base de datos, donde varios procesos pueden leer pero la escritura debe de hacerse en exclusión mutua.” Su resolución esta en un fichero aparte.

26 Aplicaciones 7 . Aplicaciones
Servicios Web: la mayoría de los servicios basados en sockets. Demonios de http (cliente y servidor). Motores de servlets. Servidores de aplicaciones. Cálculo Numérico: tratan de maximizar el rendimiento haciendo uso del paralelismo. Procesamiento de entrada/salida: los programas concurrentes pueden utilizar los tiempos de espera perdidos en operaciones lentas de entrada/salida y , por lo tanto hacer un uso más eficiente de los recursos del sistema. Simulación: estimación de productividad de un sistema y video juegos. Aplicaciones basadas en IGU: la concurrencia permite el uso de controles incluso en acciones que consumen mucho tiempo.


Descargar ppt "TEMA 2. Programación Concurrente"

Presentaciones similares


Anuncios Google