Multitarea en Java - gpd.sip.ucm.esgpd.sip.ucm.es/rafa/docencia/programacion/tema4/hebras.pdf ·...

35
Multitarea en Java Rafa Caballero - UCM

Transcript of Multitarea en Java - gpd.sip.ucm.esgpd.sip.ucm.es/rafa/docencia/programacion/tema4/hebras.pdf ·...

Page 1: Multitarea en Java - gpd.sip.ucm.esgpd.sip.ucm.es/rafa/docencia/programacion/tema4/hebras.pdf · ¿Para qué? Programas que tengan que realizar varias tareas de manera simultánea

Multitarea en Java

Rafa Caballero - UCM

Page 2: Multitarea en Java - gpd.sip.ucm.esgpd.sip.ucm.es/rafa/docencia/programacion/tema4/hebras.pdf · ¿Para qué? Programas que tengan que realizar varias tareas de manera simultánea

Programa Monoproceso (monotarea)

En cada momento hay una única instrucción ejecutándose

Se dice que el programa es monotarea, o monoproceso o monohebra (o single threading).

Rafa Caballero Rafa Caballero -- UCMUCM

Page 3: Multitarea en Java - gpd.sip.ucm.esgpd.sip.ucm.es/rafa/docencia/programacion/tema4/hebras.pdf · ¿Para qué? Programas que tengan que realizar varias tareas de manera simultánea

Programa multiproceso

En algún punto el programa se divide en varios procesos (threads) que se ejecutan (aparentemente) de manera simultánea

Programa multiproceso, multitarea, multihebra (o multithreading)

Rafa Caballero Rafa Caballero -- UCMUCM

Page 4: Multitarea en Java - gpd.sip.ucm.esgpd.sip.ucm.es/rafa/docencia/programacion/tema4/hebras.pdf · ¿Para qué? Programas que tengan que realizar varias tareas de manera simultánea

¿Para qué?

Programas que tengan que realizar varias tareas de manera simultánea

Programas en los que la ejecución de una parte requiera tiempo y no deba detener el resto del programa

Rafa Caballero Rafa Caballero -- UCMUCM

Page 5: Multitarea en Java - gpd.sip.ucm.esgpd.sip.ucm.es/rafa/docencia/programacion/tema4/hebras.pdf · ¿Para qué? Programas que tengan que realizar varias tareas de manera simultánea

¿Para qué ? Ejemplo 1

Programa que controla sensores en una fábrica: Los procesos que se encargan de controlar sensoresdiferentes son independientes y los sensores deben controlarse de manera simultánea

Programa

Temperatura

Presión Tiempo

Combustible

Rafa Caballero Rafa Caballero -- UCMUCM

Page 6: Multitarea en Java - gpd.sip.ucm.esgpd.sip.ucm.es/rafa/docencia/programacion/tema4/hebras.pdf · ¿Para qué? Programas que tengan que realizar varias tareas de manera simultánea

¿Para qué? Ejemplo 2

Durante la impresión de un documento (tarea que puede tomar tiempo) el programa puede y debe continuar ejecutándose.

Rafa Caballero Rafa Caballero -- UCMUCM

Programa

Page 7: Multitarea en Java - gpd.sip.ucm.esgpd.sip.ucm.es/rafa/docencia/programacion/tema4/hebras.pdf · ¿Para qué? Programas que tengan que realizar varias tareas de manera simultánea

Multitarea en Java

Idea: Definir clases especiales para las tareas que requieran ejecutarse en una hebra de ejecución (thread) separada

Estas clases deben incluir la función especial public void run(), equivalente a main() pero para hebras

Los objetos de la clase serán inicializados desde otra clase con el método start()

Rafa Caballero Rafa Caballero -- UCMUCM

Page 8: Multitarea en Java - gpd.sip.ucm.esgpd.sip.ucm.es/rafa/docencia/programacion/tema4/hebras.pdf · ¿Para qué? Programas que tengan que realizar varias tareas de manera simultánea

Clase para multitarea

2 Métodos:

n Mediante herencia (extensión) de la clase java.lang.Thread

n Mediante la implementación del interfaz java.lang.Runnable

Rafa Caballero Rafa Caballero -- UCMUCM

Page 9: Multitarea en Java - gpd.sip.ucm.esgpd.sip.ucm.es/rafa/docencia/programacion/tema4/hebras.pdf · ¿Para qué? Programas que tengan que realizar varias tareas de manera simultánea

Ejemplo: extensión de Thread

El programa irá escribiendo dos sucesiones ascendentes de números simultáneamente

Una hebra por cada contador

Rafa Caballero Rafa Caballero -- UCMUCM

Page 10: Multitarea en Java - gpd.sip.ucm.esgpd.sip.ucm.es/rafa/docencia/programacion/tema4/hebras.pdf · ¿Para qué? Programas que tengan que realizar varias tareas de manera simultánea

Ejemplo: Contadores (Versión 1)class Contador extends Thread {private int inicio,fin; // valor inicial y final del contadorprivate String nombre; // nombre de la hebra

// constructor con los valores iniciales y final y el nombrepublic Contador(int desde, int hasta, String id) {inicio = desde; fin = hasta; nombre = id;

}// función principalpublic void run() {

System.out.println(nombre+ " empieza...");for (int i = inicio; i <= fin; i++) {

System.out.print (nombre+" dice: "+i + ". ");try{ sleep(10); // paramos una centesima de segundo

} catch (InterruptedException e) { e.printStackTrace(); }}

System.out.println(nombre + " acaba.");}

}Rafa Caballero Rafa Caballero -- UCMUCM

Page 11: Multitarea en Java - gpd.sip.ucm.esgpd.sip.ucm.es/rafa/docencia/programacion/tema4/hebras.pdf · ¿Para qué? Programas que tengan que realizar varias tareas de manera simultánea

Ejemplo: Contadores (Versión 1)// clase principal: esta clase inicializara las hebraspublic class principal {

static public void main(String[] args) {// al declararlas NO comienzanContador hebraA = new Contador(1, 10, "HebraA");Contador hebraB = new Contador(20, 30, "HebraB");

System.out.println("Vamos a iniciar las dos hebras");// ahora comienzanhebraA.start();hebraB.start();System.out.println("Hebras inicializadas");

// hacemos un poco de tiempo antes de despedirnosfor (int i=0; i<50000000; i++) ;System.out.println("Programa principal terminado");}

} // principalRafa Caballero Rafa Caballero -- UCMUCM

Page 12: Multitarea en Java - gpd.sip.ucm.esgpd.sip.ucm.es/rafa/docencia/programacion/tema4/hebras.pdf · ¿Para qué? Programas que tengan que realizar varias tareas de manera simultánea

Ejemplo: contadores

Una ejecución del programa:

Vamos a iniciar las dos hebrasHebras inicializadasHebraA empieza...HebraA dice: 1. HebraB empieza...HebraB dice: 20. HebraA dice: 2. HebraB dice: 21. HebraA dice: 3.

HebraB dice: 22. HebraA dice: 4. Programa principal terminadoHebraB dice: 23. HebraA dice: 5. HebraB dice: 24. HebraA dice: 6.

HebraB dice: 25. HebraA dice: 7. HebraB dice: 26. HebraA dice: 8. HebraB dice: 27. HebraA dice: 9. HebraB dice: 28. HebraA dice: 10. HebraB dice: 29. HebraA acaba.

HebraB dice: 30. HebraB acaba.

Rafa Caballero Rafa Caballero -- UCMUCM

Page 13: Multitarea en Java - gpd.sip.ucm.esgpd.sip.ucm.es/rafa/docencia/programacion/tema4/hebras.pdf · ¿Para qué? Programas que tengan que realizar varias tareas de manera simultánea

Ejemplo: contadores

HebraB dice: 29HebraA dice:10

HebraB acabaHebraA acaba

HebraB dice: 28HebraA dice:9

HebraB dice: 27HebraA dice:8

HebraB dice: 26HebraA dice:7

HebraB dice: 25HebraA dice:6

HebraB dice: 24HebraA dice:5

HebraB dice: 23Programa Principal TerminadoHebraA dice:4

HebraB dice: 22HebraA dice:3

HebraB dice: 21HebraA dice:2

HebraB dice: 20HebraA dice:1

Hebra B empieza…HebraA empieza…

Hebras Inicializadas

Vamos a iniciar las dos hebras

Rafa Caballero Rafa Caballero -- UCMUCM

Page 14: Multitarea en Java - gpd.sip.ucm.esgpd.sip.ucm.es/rafa/docencia/programacion/tema4/hebras.pdf · ¿Para qué? Programas que tengan que realizar varias tareas de manera simultánea

Ejemplo: Interfaz Runnable

Se utiliza generalmente cuando la clase ya hereda de otra clase y por tanto no puede heredar de Thread

class Hebra extends loquesea implements Runnable {

……}

Rafa Caballero Rafa Caballero -- UCMUCM

Page 15: Multitarea en Java - gpd.sip.ucm.esgpd.sip.ucm.es/rafa/docencia/programacion/tema4/hebras.pdf · ¿Para qué? Programas que tengan que realizar varias tareas de manera simultánea

Ejemplo: Contadores (versión 2)class Contador implements Runnable {

private int inicio,fin; // valor inicial y final del contadorprivate String nombre; // nombre de la hebra

// constructor con los valores iniciales y final y el nombrepublic Contador(int desde, int hasta, String id) {inicio = desde; fin = hasta; nombre = id;

}

public void run() {System.out.println(nombre+ " empieza...");for (int i = inicio; i <= fin; i++) {

System.out.print (nombre+" dice: "+i + ". ");try{ Thread.sleep(10); // paramos una centesima de segundo

} catch (InterruptedException e) { e.printStackTrace(); }}

System.out.println(nombre + " acaba.");}

}Rafa Caballero Rafa Caballero -- UCMUCM

Page 16: Multitarea en Java - gpd.sip.ucm.esgpd.sip.ucm.es/rafa/docencia/programacion/tema4/hebras.pdf · ¿Para qué? Programas que tengan que realizar varias tareas de manera simultánea

Ejemplo: Contadores (versión 2)// clase principal: esta clase inicializara las hebraspublic class principal {

static public void main(String[] args) {// al declararlas NO comienzanThread hebraA = new Thread (new Contador(1, 10, "HebraA"));Thread hebraB = new Thread (new Contador(20, 30, "HebraB"));

// ahora comienzanhebraA.start();hebraB.start();System.out.println("Hebras inicializadas");

// hacemos un poco de tiempo antes de despedirnosfor (int i=0; i<50000000; i++) ;System.out.println("Programa principal terminado");}

} // principal

Contador hebraA = new Contador(1, 10, "HebraA");Contador hebraB = new Contador(20, 30, "HebraB");

Rafa Caballero Rafa Caballero -- UCMUCM

Page 17: Multitarea en Java - gpd.sip.ucm.esgpd.sip.ucm.es/rafa/docencia/programacion/tema4/hebras.pdf · ¿Para qué? Programas que tengan que realizar varias tareas de manera simultánea

Comunicación entre hebras

La forma de comunicarse consiste usualmente en compartir un mismo objeto

Generalmente el objeto se pasa como parámetro en la constructora de la clase hebra

Rafa Caballero Rafa Caballero -- UCMUCM

Page 18: Multitarea en Java - gpd.sip.ucm.esgpd.sip.ucm.es/rafa/docencia/programacion/tema4/hebras.pdf · ¿Para qué? Programas que tengan que realizar varias tareas de manera simultánea

Ejemplo: Juego para adivinar un número

ÁrbitroNúmero: 5

Jugador

4

2 7

3

Rafa Caballero Rafa Caballero -- UCMUCM

Page 19: Multitarea en Java - gpd.sip.ucm.esgpd.sip.ucm.es/rafa/docencia/programacion/tema4/hebras.pdf · ¿Para qué? Programas que tengan que realizar varias tareas de manera simultánea

Ejemplo: Juego para adivinar un número

3 Clases:n Principal: Inicializa el árbitro y lanza las hebras

de los jugadoresn Árbitro: Contiene el número a adivinar, el turno

y muestra el resultadon Jugador: Extiende Thread e incluye al árbitro.

Rafa Caballero Rafa Caballero -- UCMUCM

Page 20: Multitarea en Java - gpd.sip.ucm.esgpd.sip.ucm.es/rafa/docencia/programacion/tema4/hebras.pdf · ¿Para qué? Programas que tengan que realizar varias tareas de manera simultánea

Ejemplo: Juego para adivinar un número

public class Principal {

public static void main(String[] args) {// creamos el árbitro y los jugadores

Arbitro arbitro = new Arbitro(3); // 3 jugadores

Jugador j1 = new Jugador(1,arbitro);Jugador j2 = new Jugador(2,arbitro);Jugador j3 = new Jugador(3,arbitro);

// ponemos a los jugadores en marchaj1.start(); j2.start(); j3.start();

}}

Rafa Caballero Rafa Caballero -- UCMUCM

Page 21: Multitarea en Java - gpd.sip.ucm.esgpd.sip.ucm.es/rafa/docencia/programacion/tema4/hebras.pdf · ¿Para qué? Programas que tengan que realizar varias tareas de manera simultánea

Ejemplo: Juego para adivinar un número

class Arbitro {private int totalJugadores; // núm. de jugadoresprivate int turno; // a quién le tocaprivate int numero; // número a adivinarprivate boolean acabo; // true cuando se haya terminado el juego

public Arbitro(int nJugadores) {// constructoratotalJugadores = nJugadores;turno = 1+(int) (totalJugadores*Math.random());numero = 1+(int) (10*Math.random()); // número entre 1 y 10acabo = false;

} public int toca() { return turno; }public boolean seAcabo() { return acabo; }public synchronized void nuevaJugada(int jugador, int suNumero) {…}

}Rafa Caballero Rafa Caballero -- UCMUCM

Page 22: Multitarea en Java - gpd.sip.ucm.esgpd.sip.ucm.es/rafa/docencia/programacion/tema4/hebras.pdf · ¿Para qué? Programas que tengan que realizar varias tareas de manera simultánea

Ejemplo: Juego para adivinar un número

public synchronized void nuevaJugada(int jugador, int suNumero){

if (jugador == toca()) { // ha acertadoSystem.out.println(“Jugador”+jugador+" dice: "+suNumero);if (suNumero == numero) {

System.out.println(“Jugador “+jugador + " gana!!!");acabo = true;

} else // ha fallado. ver a quien le toca ahoraif (turno == totalJugadores) turno = 1;else turno++;

}else System.out.println(jugador+" trata de hacer trampa!");

}

Rafa Caballero Rafa Caballero -- UCMUCM

Page 23: Multitarea en Java - gpd.sip.ucm.esgpd.sip.ucm.es/rafa/docencia/programacion/tema4/hebras.pdf · ¿Para qué? Programas que tengan que realizar varias tareas de manera simultánea

Ejemplo: Juego para adivinar un número

class Jugador extends Thread {Arbitro arbitro; int identificador;

public Jugador( int elId,Arbitro elArbitro) {arbitro = elArbitro; identificador = elId;

}public void run() {

while (arbitro.seAcabo() == false) { // hasta el fin del juegoif (arbitro.toca()==identificador) { // es nuestro turno

int jugada = 1+(int) (10*Math.random());arbitro.nuevaJugada(identificador,jugada);

} // if} // while

} // run}

Rafa Caballero Rafa Caballero -- UCMUCM

Page 24: Multitarea en Java - gpd.sip.ucm.esgpd.sip.ucm.es/rafa/docencia/programacion/tema4/hebras.pdf · ¿Para qué? Programas que tengan que realizar varias tareas de manera simultánea

Ejemplo: Juego para adivinar un número

Una ejecución del programa:

Jugador 3 dice: 9

Jugador 1 dice: 2

Jugador 2 dice: 6

Jugador 3 dice: 7

Jugador 1 dice: 2

Jugador 2 dice: 5

Jugador 2 gana!!!

Rafa Caballero Rafa Caballero -- UCMUCM

Page 25: Multitarea en Java - gpd.sip.ucm.esgpd.sip.ucm.es/rafa/docencia/programacion/tema4/hebras.pdf · ¿Para qué? Programas que tengan que realizar varias tareas de manera simultánea

Ejemplo: Juego para adivinar un número

Observaciones:

n Aunque cada hebra tenga su variable árbitro todas son referencias al mismo objeto

n Con synchronized se protegen aquellas funciones que no se quiera que se puedan interrumpir por otra hebra

Rafa Caballero Rafa Caballero -- UCMUCM

Page 26: Multitarea en Java - gpd.sip.ucm.esgpd.sip.ucm.es/rafa/docencia/programacion/tema4/hebras.pdf · ¿Para qué? Programas que tengan que realizar varias tareas de manera simultánea

Ejercicio: Control de stock

Se sabe que a un almacén llegan piezas cada 8 horas. La cantidad de piezas oscila cada vez entre 400 y 1000

Del almacén salen cada 24 horas piezas hacia la fábrica, a un ritmo de entre 2000 y 2500 piezas (todas a la vez)

El almacén parte de 8000 piezas y tiene una capacidad máxima de 20000 piezas

Rafa Caballero Rafa Caballero -- UCMUCM

Page 27: Multitarea en Java - gpd.sip.ucm.esgpd.sip.ucm.es/rafa/docencia/programacion/tema4/hebras.pdf · ¿Para qué? Programas que tengan que realizar varias tareas de manera simultánea

Ejercicio: Control de stock

El programa debe simular este proceso parando si:

n Llega un nuevo cargamento y ya no cabe en el almacén

n La fábrica necesita piezas pero no hay suficientes piezas en el almacén

Rafa Caballero Rafa Caballero -- UCMUCM

Page 28: Multitarea en Java - gpd.sip.ucm.esgpd.sip.ucm.es/rafa/docencia/programacion/tema4/hebras.pdf · ¿Para qué? Programas que tengan que realizar varias tareas de manera simultánea

Ejercicio: Control de stock

Rafa Caballero Rafa Caballero -- UCMUCM

Page 29: Multitarea en Java - gpd.sip.ucm.esgpd.sip.ucm.es/rafa/docencia/programacion/tema4/hebras.pdf · ¿Para qué? Programas que tengan que realizar varias tareas de manera simultánea

Ejercicio: Control de stock

Vamos a hacer la simulación con 4 clases:

n Retirada: Simula retirada de piezas hacia la fábrica. Además escribe el número de días transcurridos desde el comienzo

n Envío: Simula el envío de piezas al almacén

n Almacén: Simula el almacén. Tendrá funciones para atender las llegadas y las salidas de piezas. Controlará si hay algún error y mostrará mensajes con el movimiento del almacén

n Principal: Función main que pondrá en marcha la aplicación

Rafa Caballero Rafa Caballero -- UCMUCM

Page 30: Multitarea en Java - gpd.sip.ucm.esgpd.sip.ucm.es/rafa/docencia/programacion/tema4/hebras.pdf · ¿Para qué? Programas que tengan que realizar varias tareas de manera simultánea

Ejercicio: Control de stock

Envío y Retirada heredarán de la clase Thread y compartirán el objeto tipo Almacén.

Ambas pararán cuando el Almacén indique que hay un error (bien porque no hay piezas para atender un pedido o porque no caben más piezas y hay un envío)

Rafa Caballero Rafa Caballero -- UCMUCM

Page 31: Multitarea en Java - gpd.sip.ucm.esgpd.sip.ucm.es/rafa/docencia/programacion/tema4/hebras.pdf · ¿Para qué? Programas que tengan que realizar varias tareas de manera simultánea

Ejercicio: Control de stockPara simular el tiempo, las funciones run() de las clases Retirada y Envio incluirán sendas llamadas a sleep:

n En el caso de Retirada:try{ sleep(2400); // simulación de un día } catch (InterruptedException e) { e.printStackTrace(); }

n En el caso de Envio:try{ sleep(800); // simulación de 8 horas } catch (InterruptedException e) { e.printStackTrace(); }

De está manera habrá 3 envíos por cada retirada

Rafa Caballero Rafa Caballero -- UCMUCM

Page 32: Multitarea en Java - gpd.sip.ucm.esgpd.sip.ucm.es/rafa/docencia/programacion/tema4/hebras.pdf · ¿Para qué? Programas que tengan que realizar varias tareas de manera simultánea

Ejercicio: Control de stock

// Estructura de la clase almacén:class Almacen {private final int maximo=20000; // capacidad del almacénprivate int stock = 8000; // núm. Piezas en el almacén. Al principio 8000private boolean hayError = false; // al principio no hay error

// Método entrada: ‘carga’ es la cantidad de piezas que llegan al almacén// si la carga + el stock superan el maximo mostrará un mensaje de error y // pondrá hayErrora true. En otro caso incrementará el stock con la ‘carga’public void entrada(int carga) { ….}

// Método salida: ‘piezas’ es la cantidad de piezas pedida por la fábrica// Si stock < piezas se mostrará un mensaje de erro y se pondrá // hayError a true. En otro caso se decrementará el stock en ‘piezas’public void salida(int piezas) { } // pedido

public boolean error() { return hayError; }}

Rafa Caballero Rafa Caballero -- UCMUCM

Page 33: Multitarea en Java - gpd.sip.ucm.esgpd.sip.ucm.es/rafa/docencia/programacion/tema4/hebras.pdf · ¿Para qué? Programas que tengan que realizar varias tareas de manera simultánea

Ejercicio: Control de stock

…...Día 41Pedido de 2409 piezasHay 699 piezas en el almacénLlegan 586 piezasHay 1285 piezas en el almacénLlegan 404 piezasHay 1689 piezas en el almacénLlegan 462 piezasHay 2151 piezas en el almacén

Día 42Pedido de 2483 piezasNo hay piezas suficientes!

Día 1Pedido de 2179 piezasHay 5821 piezas en el almacénLlegan 744 piezasHay 6565 piezas en el almacénLlegan 580 piezasHay 7145 piezas en el almacénLlegan 624 piezasHay 7769 piezas en el almacén

Día 2Pedido de 2420 piezasHay 5349 piezas en el almacén

Rafa Caballero Rafa Caballero -- UCMUCM

Page 34: Multitarea en Java - gpd.sip.ucm.esgpd.sip.ucm.es/rafa/docencia/programacion/tema4/hebras.pdf · ¿Para qué? Programas que tengan que realizar varias tareas de manera simultánea

Ejercicio: Control de stock

Resultados de 20 simulaciones

0

10

20

30

40

50

60

70

80

1ª 4ª 7ª 10ª 13ª 16ª 19ª

Días hastaquedarse vacío

Rafa Caballero Rafa Caballero -- UCMUCM

Page 35: Multitarea en Java - gpd.sip.ucm.esgpd.sip.ucm.es/rafa/docencia/programacion/tema4/hebras.pdf · ¿Para qué? Programas que tengan que realizar varias tareas de manera simultánea

Ejercicio: Control de stock

Sugerencia: probar con otros valores

Por ejemplo, con 4 envíos por día se comprobará que el almacén se llena en aproximadamente 25 días

Rafa Caballero Rafa Caballero -- UCMUCM