43
1 CONTENIDO Revisión del Concepto de Hilo Técnicas de Creación de Hilos Ciclo de Vida. Control de Hilos Prioridades Hilos y Sistemas Operativos BIBLIOGRAFÍA RECOMENDADA: [Eck02] Eckel, B. Thinking in Java. Prentice Hall. 2002 [Göe06] Göetz et al. Java Concurrency in Practice, 2006 [Oaks04] Oaks & Wong. Java Threads. O`Reilly, 2004. TEMA 3: Creación y Control De Threads en Java

Threads java

  • Upload
    atomeu

  • View
    4.870

  • Download
    4

Embed Size (px)

DESCRIPTION

Threads in javaConcurrent Programming in JavaConcurrency in Java

Citation preview

Page 1: Threads java

1

CONTENIDORevisión del Concepto de HiloTécnicas de Creación de HilosCiclo de Vida. Control de HilosPrioridadesHilos y Sistemas Operativos

BIBLIOGRAFÍA RECOMENDADA:[Eck02] Eckel, B. Thinking in Java. Prentice Hall. 2002[Göe06] Göetz et al. Java Concurrency in Practice, 2006[Oaks04] Oaks & Wong. Java Threads. O`Reilly, 2004.

TEMA 3: Creación y Control De Threads en Java

Page 2: Threads java

2

Dentro de un proceso, el control suele seguir un hilo de ejecución, que comienza con main, continúa con el resto de las instrucciones, y termina con el proceso.Java soporta varios hilos de ejecución y por tanto, los programas de Java pueden crear dentro de sí mismos varias secuencias de ejecución concurrentes.A diferencia de los procesos concurrentes, que son independientes, los hilos de un mismo proceso comparten el espacio de direcciones virtuales, y los recursos del s.o.Por tanto, cada hilo tiene acceso a los datos y procedimientos del proceso, pero poseen su propio contador de programa y pila de llamadas a procedimientos.Los problemas que aparecen con una concurrencia multihilo son los habituales: exclusión mutua y sincronización, y con menor importancia, esquema de prioridades e interbloqueos.Se pueden tener hilos de dos formas: herencia de la clase Thread o implementación de la interfaz Runnable.

Revisión del Concepto de Hilo (Thread)

Thread Clase Extendida

extends

© Antonio Tomeu Creación y Control de Thread en Java

Page 3: Threads java

3

Estamos en programación concurrente… y toca usar hilosSe optimiza el uso de la CPUSe modelan mejor determinados problemas… o noEl problema no admite otra solución razonable, por ejemplo

programar un servidor decentediseñar un GUI interactivo

Razones para Usar Hilos…

© Antonio Tomeu Creación y Control de Thread en Java

Page 4: Threads java

4

Thread

void run()void start()...

Thread()Thread(Runnable target)

subclase

implementación

MiThread

void run(){...

}

RunnableObject

void run()//imp.{...

}

parámetro

Runnable

implements

void run()

API Java paraThreads: Marco General

extends

Page 5: Threads java

5

public class Thread extends Object implements Runnable {

public Thread();public Thread(String name);public Thread(Runnable target);public Thread(Runnable target,

String name);public Thread(Runnable target,

String name, long stackSize);

public void run();public void start();public void join()...

}

Clase Thread: API Básica

© Antonio Tomeu Creación y Control de Thread en Java

Page 6: Threads java

6

class Ejemplo_Hilos1 extends Thread

{ public Ejemplo_Hilos1 (int Tope) //constructor{T = Tope;}

public void run () //sobreescritura del metodo run{for (int i = 1; i <= T; i++)System.out.println (i); //aquí comportamiento del

} //hilo deseado private int T ;

}

Concurrencia con Hilos por Herencia de la clase Thread

© Antonio Tomeu Creación y Control de Thread en Java

Page 7: Threads java

7

class Prueba_Hilo1 //Hace uso de la clase anterior{public static void main (String [] args)throws InterruptedException

{Ejemplo_Hilos1 Hilo1 = new Ejemplo_Hilos1 (5);Ejemplo_Hilos1 Hilo2 = new Ejemplo_Hilos1 (15);Hilo1.start (); //Ahora se lanzan ambos hilos...Hilo2.start (); //con apertura de co-rutinaHilo1.join ();Hilo2.join (); // y cierre de co-rutinaSystem.out.println ("Hilos terminados");

}}

© Antonio Tomeu Creación y Control de Thread en Java

Page 8: Threads java

8

Secuencia Temporal de Co-rutina con Hilos

Tiempo

EJECUCIÓN

Programa principalHilo 1

Hilo 2

Condición de Espera

(join)

© Antonio Tomeu Creación y Control de Thread en Java

Page 9: Threads java

9

Dado el código anterior, incremente el número de hilos y el número de vueltas que cada hilo da. Recompile y ejecute.¿Observa entrelazado en la salida?Continúe aumentando el número de hilos (por ejemplo definiendo un array de hilos)¿Dónde está el límite práctico al número de hilos (% uso de CPU próximo al 100%)?Escriba un “hola mundo” concurrente.

EJERCICIOS

© Antonio Tomeu Creación y Control de Thread en Java

Page 10: Threads java

10

Revisitando incConcurrente.java

Descárguelo (Tema 1)Array de ThreadsDato común: nVariables staticpermiten compartir memoria entre threadsSecciones críticasCondición de ConcursoResultados no consistentes Modelo de Memoria de Java

© Antonio Tomeu Creación y Control de Thread en Java

Page 11: Threads java

11

public class Hola_Adios extends Thread{public Hola_Adios (String Palabra){Cadena = Palabra;}

private void otrometodo(){System.out.println (“otro metodo”);}

public void run (){

for (;;)System.out.println (Cadena);this.otrometodo(); // run puede invocar otros metodos de la claseInteger p = new Integer(3); //o crear los objetos que necesita

}

public static void main (String [] args){new Hola_Adios ("Hola").start ();new Hola_Adios ("Hola").start ();new Hola_Adios ("Hola").start ();new Hola_Adios ("Adios").start ();

}private String Cadena;

} © Antonio Tomeu Creación y Control de Thread en Java

Page 12: Threads java

12

Escriba un hilo que muestre pares o impares, según se indique en el constructor, un número dado de veces, que también se indicaráen el constructor. Llame a la clase ParImpar.javaEscriba ahora un código que hago uso de la clase anterior. Llámelo Usa_ParImpar.java Observe el entrelazado.Aloje una variable compartida en una clase llamada Critica.java. Provea métodos para incrementar la variable y para mostrar su contenido. ¿Habría condiciones de concurso?Escriba ahora hilos que utilicen un objeto común de esa clase.Láncelos en un código aparte. ¿Observa algo raro?Aunque no lo observe ¿Qué puede ocurrir potencialmente?Realmente ¿hacía falta la clase Critica.java?

EJERCICIOS

© Antonio Tomeu Creación y Control de Thread en Java

Page 13: Threads java

13

public interface Runnable{public void run();

}

Es una interface de java.langCualquier clase X que la implemente expresa ejecución concurrenteObjetos de la clase X son parámetros del constructor de Thread

Concurrencia con Hilos por Implementación de la Interfaz Runnable

© Antonio Tomeu Creación y Control de Thread en Java

Page 14: Threads java

14

public class Ximplements Runnable

{...public void run(){//codigo concurrente}

}

A = new X()

Objeto claseX

contienecódigo concurrente

H = new Thread(A)

Código concurrenteen ejecución

A

HH.start()

A

© Antonio Tomeu Creación y Control de Thread en Java

Page 15: Threads java

15

public class UsoRunnable implements Runnable{

private String Cadena;public UsoRunnable(String Palabra){Cadena=Palabra;}

public void run() {for(;;)System.out.println(Cadena);

}public static void main(String[] args){

UsoRunnable Hilo1 = new UsoRunnable("Hola");UsoRunnable Hilo2 = new UsoRunnable("Adios");new Thread(Hilo1).start();new Thread(Hilo2).start();

}}

Concurrencia con Hilos por Implementación de la Interfaz Runnable

© Antonio Tomeu Creación y Control de Thread en Java

Page 16: Threads java

16

/*Otra forma de crear hilos concurrentes dandoles nombre*@author Antonio J. Tomeu*/public class UsoRunnable2 implements Runnable{private int Iter;public UsoRunnable2(int Dato){Iter = Dato;}

public void run(){

for(int i=1;i<=Iter;i++)System.out.println("Trabajando");

}

public static void main(String[] args)throws InterruptedException

{Runnable HiloA = new UsoRunnable2(100);Runnable HiloB = new UsoRunnable2(200);Runnable HiloC = new UsoRunnable2(100);

© Antonio Tomeu Creación y Control de Thread en Java

Page 17: Threads java

17

//version del constructor Thread crea hilo con un nombreThread A = new Thread(HiloA, "Mi Hilo");Thread B = new Thread(HiloB, "Tu Hilo"); //sin nombreThread C = new Thread(HiloC);A.start();B.start();A.join();B.join();C.join();

//metodo getName() de objetos de la clase Thread devuelve el nombre//del hilo

System.out.println(A.getName());System.out.println(B.getName());

//no tenia nombre, pero se le dio uno en tiempo de ejecucion.System.out.println(C.getName());

}}

© Antonio Tomeu Creación y Control de Thread en Java

Page 18: Threads java

18

Inconveniente de heredar de Thread: No permite heredar de otras clases.Alternativa de creación de hilos: Implementación de la interfaz RunnableSobreescribir siempre el método runLos objetos que implementan Runnable deben ser lanzados explícitamenteSe hace creando un objeto Thread cuyo parámetro es un objeto RunnableLuego se llama al método start del objeto ThreadcreadoTécnica recomendada: implementar la interfaz

mparativa de Métodos de Multithreading

© Antonio Tomeu Creación y Control de Thread en Java

Page 19: Threads java

19

Escriba ahora código de hilo que implemente la interfaz Runnable. Déle al hilo acceso compartido a una variable común. Llámelo hiloRunn.javaEscriba un programa que haga uso de los hilos anteriores. Llámelo usahilRunn.java. Verifique la sobreescritura.Escriba código de hilo para el lanzamiento de una co-rutina. Cada hilo deberá desplegar su nombre. Desarrolle una versión con cada herramienta de creación de hilos. Llámelas Co_rutina_T.java y Co_rutina_I.javaInspeccione el API de la clase Thread. En C/C++, el API de pthread.h incluye herramientas de sincronización mediante mutex. ¿Puede decirse lo mismo de la clase Thread en java?Finalmente, desarrolle una versión en java del algoritmo de Lamportpara dos procesos utilizando hilos heredados de Thread .

EJERCICIOS

© Antonio Tomeu Creación y Control de Thread en Java

Page 20: Threads java

20

Otras técnicas de creación de Threads

Pool de ThreadsPermiten reutilizar hilosDeben ajustarse (tuning) según aplicaciónAnálisis en Tema 6

© Antonio Tomeu Creación y Control de Thread en Java

Page 21: Threads java

21

Hilo Inexistente

Hilo nuevo

Ejecutable

Bloqueado Muerto

start()

new Thread(), new Thread(Runnable t)

recolección de basura

wait(), join()

notify(), notifyAll()

destroy()-fin_ejecución//derogado

destroy()//derogado

destroy()//derogado

Hilo Inexistente

Objetos Thread: Ciclo de Vida

Page 22: Threads java

22

CLASEThread: API DE CONTROLUn hilo t1 puede se controlado por otro hilo t0 (normalmente el hilo padre) a través de los siguientes métodos de la clase Thread.

Pasa a t1 de en ejecución a listo.t1.yield()

Suspende a t1 durante t milisegundos.t1.sleep(int t)

Mata a t1. DEROGADOt1.destroy ()

Suspende a t0 y espera a que termine t1.t1.join ()

Envía una señal a t1.t1.interrupt ()

Hace que t1 vaya de bloqueado a listo. DEROGADOt1.resume ()

Envía a t1 de listo/en ejecución a bloqueado.t1.suspend ()

Comprueba si el hilo t1 está vivo.t1.isAlive()

Mata al hilo t1. DEROGADOt1.stop ()

Lanza el hilo t1t1.start ()

Determina si t0 tiene permiso para controlar a t1.

t1.checkAccess()

ComportamientoMétodo

© Antonio Tomeu Creación y Control de Thread en Java

Page 23: Threads java

23

import java.io.*; Import java.util.*;public class Control extends Thread{//No declara constructor explicito. Usa el disponible por defecto

public void run(){

for(;;)System.out.println("Trabajando");

}

public static void main(String[] args)throws IOException

{int c;//usando el constructor implicitoControl Hilo = new Control(); Hilo.start();

© Antonio Tomeu Creación y Control de Thread en Java

CONTROL DE Threads: Ejemplo con Métodos Derogados

Page 24: Threads java

24

for(int i=1; i<=100; i++) //entrelazado de instruccionesSystem.out.println("Hola soy el padre");

Hilo.suspend(); //USO DE METODO DEROGADO, HILO PADRE SUSPENDE A HIJO .System.out.println("Hijo suspendido");//Ahora reactivamos al hijo, que pasa a listo.System.out.println("Pulsa 1 para despertar al hijo");do {

c=System.in.read();}

while(c != -1); Hilo.resume(); //USO DE METODO DEROGADO, PASA A LISTO A HIJO//un poquito de interfoliacion otra vez.for(int i=1; i<=100; i++)System.out.println("Hola soy el padre");Hilo.stop(); //USO DE METODO DEROGADO, PADRE PARA AL HIJO

}

}

© Antonio Tomeu Creación y Control de Thread en Java

Page 25: Threads java

25

import java.io.*;public class AutoControl extends Thread{private int Vueltas;

public AutoControl(int Dato){Vueltas=Dato;}

public void run(){ //el uso de sleep exige capturar la posible excepcion. try{ for(int i=1; i<=Vueltas; i++){System.out.println(i);if(i==25){//los hilos se suspenden en la iteracion 25System.out.println("Suspension durante dos segundos");int timeout = 1000;sleep(timeout);System.out.println("Continuando");}//if}//for}catch (InterruptedException e) {return;}

}© Antonio Tomeu Creación y Control de Thread en Java

CONTROL DE Threads: Ejemplo de Replanificación Voluntaria (sleep)

Page 26: Threads java

26

public static void main(String[] args){

new AutoControl(50).start();new AutoControl(150).start();

}}

© Antonio Tomeu Creación y Control de Thread en Java

Page 27: Threads java

27

public class replaniYieldextends Thread

{private boolean hY;//indicara si el hilo cede prioridad o no…private int v;

public replaniYield(boolean hacerYield, int vueltas) {hY = hacerYield; v = vueltas;}

public void run(){for(int i=0; i<v; i++)if(i==20&&hY==true){this.yield();}//indica cesion de prioridad…else System.out.println("Hilo "+this.getName()+" en iteracion "+i);

}public static void main(String[] args) {

replaniYield h0 = new replaniYield(false, 50);replaniYield h1 = new replaniYield(false, 50);replaniYield h2 = new replaniYield(true , 50); //cedera prioridad yh0.setName("1-NoYield"); //sera o no considerardah1.setName("2-NoYield"); h2.setName("3-SIYield");h0.start(); h1.start(); h2.start();

}}

CONTROL DE Threads: Ejemplo de Cesión de Prioridad Voluntaria (yield)

© Antonio Tomeu Creación y Control de Thread en Java

Page 28: Threads java

28

CONTROL DE PRIORIDAD

Prioridad hilo hijo igual a la de hilo padreLa prioridad tiene sentido exclusivamente en el ámbito de la JVM… aunque se mapea a los hilos de sistema (OJO: EL MAPPING NO ES RIGUROSO=>INVERSIONES DE PRIORIDAD)Clase Thread:esquema de diez niveles de prioridadVer la prioridad de un hilo:

public int getPriority()

Alterar la prioridad de un hilo:public void setPriority(int p) (1<=p<=10)

© Antonio Tomeu Creación y Control de Thread en Java

Page 29: Threads java

29

package java.lang;

public class Thread implements Runnablepublic final static int Thread.MIN_PRIORITY;public final static int Thread.NORM_PRIORITY; public final static int Thread.MAX_PRIORITY;public void setPriority(int prioridad);public int getPriority():

CLASE Thread: API DE CONTROL DE PRIORIDAD

© Antonio Tomeu Creación y Control de Thread en Java

Page 30: Threads java

30

PLANIFICACIÓN BASADA EN PRIORIDADES

Valor prioridad en JVM indica al planificador del S.O qué hilos van primero…pero no es un contrato absoluto entre ambos ya que depende:

de la implementación de la JVMdel S.O. subyacentedel mapping prioridad jvm-prioridad s.o.

© Antonio Tomeu Creación y Control de Thread en Java

Page 31: Threads java

31

public class Prioridades extends Thread{

private long dato;private static int prio = 4; //atributo de clase comun a instanciaspublic Prioridades (long n){dato=n;}

private long fac(long n){

if (n == 0) return 0;else if (n == 1) return 1;

else return(fac(n-1)*n);}

public void run(){

//this.setPriority(prio++); //ejecutar con y sin el ajuste de prioridadSystem.out.println("El factorial de "+dato+" es "+fac(dato));

}

public static void main(String[] args) {

new Prioridades(10).start(); //orden lanzamiento no es igual al ordennew Prioridades(20).start(); //de ejecución… peronew Prioridades(30).start(); //¿ajustando las prioridades?new Prioridades(40).start();new Prioridades(50).start();new Prioridades(60).start();

}}

© Antonio Tomeu Creación y Control de Thread en Java

Page 32: Threads java

32

import java.util.*;import java.text.*;

public class Trabajo implements Runnable {long n;String id;

private long fib(long n) {if (n == 0)

return 0L;if (n == 1)

return 1L;return fib(n - 1) + fib(n - 2);

}

public Trabajo(long n, String id) {this.n = n;this.id = id;

}

public void run() {Date d = new Date();DateFormat df = new SimpleDateFormat("HH:mm:ss:SSS");long startTime = System.currentTimeMillis();d.setTime(startTime);System.out.println("Iniciando trabajo " + id + " a las " + df.format(d));fib(n);long endTime = System.currentTimeMillis();d.setTime(endTime);System.out.println("Acabando trabajo " + id + " a las " + df.format(d) + " tras

" + (endTime - startTime) + " milliseconds");}

}

Page 33: Threads java

33

public class ThreadTest {

public static void main(String[] args) {

int nHilos = Integer.parseInt(args[0]);long n = Long.parseLong(args[1]);

Thread t[] = new Thread[nHilos];

for (int i = 0; i < t.length; i++) {t[i] = new Thread(new Trabajo(n, "Trabajo " + i));t[i].start();

}for (int i = 0; i < t.length; i++) {

try {t[i].join();

} catch (InterruptedException ie) {}}

}}

© Antonio Tomeu Creación y Control de Thread en Java

Page 34: Threads java

34

public class ThreadTestNuevaPrioridad {

public static void main(String[] args) {int nHilos = Integer.parseInt(args[0]);long n = Long.parseLong(args[1]);Thread t[] = new Thread[nHilos];

for (int i = 0; i < t.length; i++) {t[i] = new Thread(new Trabajo(n, "Trabajo " + i));t[i].setPriority((i % 10)+1);t[i].start();

}for (int i = 0; i < t.length; i++) {

try {t[i].join();

} catch (InterruptedException ie) {}}

}}

© Antonio Tomeu Creación y Control de Thread en Java

Page 35: Threads java

35

Compile y ejecute los códigos anteriores¿Observa inversiones de prioridad?¿A qué cree que se deben?Desarrolle ahora código de hilo sincronizado basado en prioridades (p.e. un hilo incrementa un dato y otro lo muestra, en ese orden)¿Es una estrategia válida de sincronización?¿Y con una co-rutina?

EJERCICIOS

© Antonio Tomeu Creación y Control de Thread en Java

Page 36: Threads java

36

El s.o. conoce el número de hilos que usa la JVMSe aplican uno-a-uno. (JVM a Win)El secuenciamiento de hilos java estásujeto al del s.o.Se aplican 10 prioridades en la JVM sobre 7 en el s.o.+5 prioridades de secuenciamiento

MAPPING HILOS JVM-HILOS NATIVOS DE WIN32

© Antonio Tomeu Creación y Control de Thread en Java

Page 37: Threads java

37

MAPPING PRIORIDADES JVM A WIN32

THREAD.PRIORITY_TIME_CRITICAL10 (Thread.MAX_PRIORITY)THREAD.PRIORITY_HIGHEST9THREAD.PRIORITY_HIGHEST8THREAD.PRIORITY_ABOVE_NORMAL7THREAD.PRIORITY_ABOVE_NORMAL6THREAD.PRIORITY_NORMAL5 (Thread.NORM_PRIORITY)THREAD.PRIORITY_BELOW_NORMAL4THREAD.PRIORITY_BELOW_NORMAL3THREAD.PRIORITY_LOWEST2THREAD.PRIORITY_LOWEST1 (Thread.MIN_PRIORITY)THREAD.PRIORITY_IDLE0

Prioridad Win32Prioridad Java

© Antonio Tomeu Creación y Control de Thread en Java

Page 38: Threads java

38

Pero recuerde…En general, hilos de baja prioridad obtendrán acceso al procesador cuando los de alta prioridad estén en espera.La prioridad es poco significativacuando todos los hilos compiten por el procesador.

MAPPING HILOS JVM-HILOS NATIVOS DE WIN32

© Antonio Tomeu Creación y Control de Thread en Java

Page 39: Threads java

39

Núcleos recientes implementan NativePosix Thread LibraryAplican hilos JVM a hilos del núcleo uno-a-uno bajo el modelo de SolarisLa prioridad java es un factor muy pequeño en el cálculo global del secuenciamiento

MAPPING HILOS JVM-HILOS NATIVOS DE LINUX

© Antonio Tomeu Creación y Control de Thread en Java

Page 40: Threads java

40

MAPPING PRIORIDADES JVM A PRIORIDADES DE HILOS LINUX

-510 (Thread.MAX_PRIORITY)

-49

-38

-27

-16

05 (Thread.NORM_PRIORITY)

14

23

32

41 (Thread.MIN_PRIORITY)

no contemplado0

Prioridad Linux (nice value)Prioridad Java

© Antonio Tomeu Creación y Control de Thread en Java

Page 41: Threads java

41

Solo como root (o con privilegios equivalentes, setuid)Parametrizar a la JVM indicando que tenga en cuenta las prioridades.

RESTRICCIONES DEL MAPPING PRIORIDADES JVM A LINUX

© Antonio Tomeu Creación y Control de Thread en Java

Page 42: Threads java

42

La actual especificación de la JVM no establece un modelo de planificación por prioridadesEl comportamiento puede y debe variar en diferentes máquinasEn secuencias de tareas estrictas, no es posible planificar con prioridadesAunque sí con co-rutinas, a nivel básico

CONTROL DE PRIORIDAD: CONCLUSIONES

© Antonio Tomeu Creación y Control de Thread en Java

Page 43: Threads java

43

Modelos Teóricos de Control de la ConcurrenciaVariables ComunesSemáforosRegiones CríticasMonitores

En el Próximo Tema…

© Antonio Tomeu Creación y Control de Thread en Java