Hilos BUAP Introducción Normalmente, los programas son ejecutados de forma secuencial Único flujo de control Un programa con un único flujo de control, ejecuta sólo una tarea (hilo) Dr. Ivan Olmos 2 Introducción Históricamente, los sistemas de cómputo personales sólo han tenido un único CPU Al volverse más poderosos los CPU, se desarrolló S. O. multitarea / multiproceso Programación multitarea (multihilo), multiproceso Programación (pseudo)concurrente Dr. Ivan Olmos 3 Hilos Un hilo (thread) es un flujo de control secuencial dentro de un programa public class Hola_Mundo { public static void main(String[] args) { System.out.println("Hola Mundo\n"); } } Una aplicación de control único realiza su tarea ejecutando subtareas de forma secuencial Dr. Ivan Olmos 4 Hilos Un programa puede generar dos o más hilos de ejecución, los cuales siempre dependerán de la aplicación principal P. E. Imprimir diferentes mensajes desde una aplicación principal Hola Mundo 1 Programa Principal Hola Mundo 2 Hola Mundo 3 Dr. Ivan Olmos 5 Características Generales de los Hilos Típicamente, las tareas controlan un único aspecto dentro de un programa Todas las tareas comparten los mismos recursos Aplicación Java Thread 1 Thread 2 Dr. Ivan Olmos Thread 3 6 Multitarea vs. Multiproceso Multiproceso: dos programas se ejecutan “aparentemente” a la vez, sin necesidad de tener una relación entre ellos Multitarea: dos o más tareas se ejecutan a la “vez” dentro de un mismo programa Dr. Ivan Olmos 7 Ejemplo class TestHilos extends Thread{ private String nombre; private int retardo; //constructor public TestHilos(String s, int d){ nombre = s; retardo = d; } public class hilos { public static void main(String[] args) { TestHilos t1,t2,t3; t1 = new TestHilos("hilo_1",(int)(Math.random()*2000)); t2 = new TestHilos("hilo_2",(int)(Math.random()*2000)); t3 = new TestHilos("hilo_3",(int)(Math.random()*2000)); //funcion para la ejecucion del hilo t1.start(); public void run(){ t2.start(); try{ t3.start(); sleep(retardo); } } catch(InterruptedException e){ } ; } System.out.println("hola mundo " + nombre + " " + retardo); } } Dr. Ivan Olmos 8 Programación con Hilos en Java Introducción Java permite la ejecución de diferentes hilos a partir de clases derivadas de la clase Thread, o bien a través de la implementación de la clase Runnable Métodos de Clase Thread Métodos de Instancia Dr. Ivan Olmos 10 Métodos de Clase currentThread() yield() Devuelve el objeto Thread que representa a la tarea que se esta ejecutando actualmente Permite permutar la ejecución de la tarea actual y la siguiente tarea ejecutable disponible sleep(long) Provoca que la tarea en curso entre en pausa durante un número de milisegundos indicado por “long” Dr. Ivan Olmos 11 Métodos de Instancia start() run() Cuerpo de una tarea o hilo de ejecución. Es llamado por el método start() stop() Indica al interprete de java iniciar una tarea. Inmediatamente se invoca al método run() Detiene la ejecución de una tarea y la destruye suspend() Detiene la ejecución sin destruir la tarea de sistema subyacente ni el estado de la tarea anteriormente en ejecución Dr. Ivan Olmos 12 Métodos de Instancia resume() Utilizada para revivir una tarea suspendida, aunque no se garantiza que se inicie su ejecución de forma inmediata setPriority(int) Asigna la prioridad indicada por “int” a una tarea (rango de valores: 1, …, 10). Existen constantes predefinidas como “MIN_PRIORITY”, “NORM_PRIORITY”, “MAX_PRIORITY” getPriority() Devuelve la prioridad de una tarea en curso setName(String) Permite identificar a una tarea a través de un nombre getName() Devuelve el valor actual de tipo cadena asignado como nombre a la tarea Dr. Ivan Olmos 13 Creación de Tareas en Java Implementación de la clase Runnable Extender la clase Thread class TestHilos extends Thread{ public void run(){ ... public class TestHilos implements Runnable{ Thread t; public void run(){ ... } } } } •Ventaja: hereda todos los métodos y variables de la clase Thread •Desventaja: sólo se pueden extender o derivar una vez de la clase Thread •Ventaja: hereda todos los métodos y variables de la clase Thread; además permite heredar la clase base a otras clases Dr. Ivan Olmos 14 Ejemplo 1: Runnable class NoHaceNada{ } class MiHilo extends NoHaceNada implements Runnable{ private String nombre; private int retardo; public class Hilo2 { public static void main(String[] args) { Thread hiloA = new Thread(new MiHilo("Hilo1", (int)(Math.random()*2000)), "hiloA"); Thread hiloB = new Thread(new MiHilo("Hilo2", (int)(Math.random()*2000)), "hiloB"); public MiHilo(String s, int d){ nombre = s; retardo = d; } hiloA.start(); hiloB.start(); try{ Thread.currentThread().sleep( 1000 ); } catch (InterruptedException e){} System.out.println(Thread.currentThread()); } public void run(){ try{ Thread.currentThread().sleep(retardo); } catch (InterruptedException e){} System.out.println("hola Mundo! " + nombre + " " + retardo + " " + Thread.currentThread()); } } } Dr. Ivan Olmos 15 Ejemplo 2: Thread class MiHilo extends Thread{ private String nombre; private int retardo; public class Hilos3 { public static void main(String[] args) { //constructor public MiHilo(String s, int d){ nombre = s; retardo = d; } Thread hiloA = new Thread(new MiHilo("hiloA",(int) (Math.random()*2000)),"hiloA"); Thread hiloB = new Thread(new MiHilo("hiloB",(int) (Math.random()*2000)),"hiloB"); public void run(){ try{ Thread.currentThread().sleep(retardo); } catch (InterruptedException e){} System.out.println("hola mundo! " + nombre + " " + retardo + " " + Thread.currentThread()); } } hiloA.start(); hiloB.start(); try{ Thread.currentThread().sleep(1000); } catch(InterruptedException e){} System.out.println(Thread.currentThread()); } } Dr. Ivan Olmos 16 Ejemplo 3: class TestHilos extends Thread{ private String nombre; private int retardo; //constructor public TestHilos(String s, int d){ nombre = s; retardo = d; } public class hilos { public static void main(String[] args) { TestHilos t1,t2,t3; t1 = new TestHilos("hilo_1",(int)(Math.random()*2000)); t2 = new TestHilos("hilo_2",(int)(Math.random()*2000)); t3 = new TestHilos("hilo_3",(int)(Math.random()*2000)); //funcion para la ejecucion del hilo t1.start(); public void run(){ t2.start(); try{ t3.start(); sleep(retardo); } } catch(InterruptedException e){ } ; } System.out.println("hola mundo " + nombre + " " + retardo); } } Dr. Ivan Olmos 17 Sincronización de Hilos Cuando se trabaja con hilos, es común realizar tareas de sincronización para: Determinar cuando un hilo puede operar sobre los datos comunes Tomar como entrada de un hilo la salida de otro hilo Recursos compartidos Dr. Ivan Olmos 18 Sincronización de Hilos Para sincronizar hilos es importante utilizar las funciones: wait: esperar por un evento – notify notify: avisa a cualquier proceso que esté en espera por un objeto específico Analizar el ejemplo de sincronización propuesto Dr. Ivan Olmos 19