1. Introducción a los Hilos (Threads)

Transcripción

1. Introducción a los Hilos (Threads)
Juan Carlos Castro
[email protected]
1. Introducción a los Hilos (Threads)
Los hilos son tareas que se ejecutan de forma concurrente. Por ejemplo, una
aplicación que pasa revisando si se ha establecido una conexión a Internet para
actualizarse mientras el programa principal sigue trabajando.
Nótese que en este caso no podría usarse un ciclo, pues las instrucciones son
secuénciales, es decir, un bloque del programa no se ejecutará en tanto otro se esté
ejecutando. Por ejemplo, en el caso anterior el escuchador de actualización tendría un
código parecido al siguiente:
while(!conexionEstablecida()){
/* mientras no se establezca la conexión no hacer nada */
}
descargar() // después de que se estableció la conexión, descargar.;
El problema de hacer esto así es que una vez que el proceso principal invoca al
método escuchador este consumirá todos los recursos de dicho proceso pues se quedará
ejecutando el ciclo hasta establecer una conexión. La forma de solucionar este problema
sería creando una tarea nueva.
2. Creación de Hilos
La creación de hilos es bastante sencilla, si bien la clase Thread, que se encarga
de esto tiene varios constructores en esta sección se explicará el más sencillo.
Dicho constructor es el siguiente:
public Thread(Runnable r)
Runnable (ejecutable) es una interfaz que contiene al método run(), el cuál será
invocado cuando el hilo inicie su ejecución. Una vez que se termine la ejecución de
run(), se detiene la ejecución del hilo.
Por ejemplo se tiene un JFrame que debe desplegar la hora y la fecha. Este
JFrame, llamado Reloj, debe incorporar la interfaz Runnable en su definición de clase
de la siguiente manera:
public class Reloj extends JFrame implements ActionListener, Runnable{
// …
}
Ahora hay que agregar las dos tareas: una que muestre la hora y otra que
muestre la fecha:
Thread t_Hora = new Thread(this);
Thread t_Fecha=new Thread(this);
Como Thread recibe un objeto Runnable y la clase Reloj implementa dicha
interfaz entonces el objeto Reloj se pasa a si mismo (this hace referencia al objeto
mismo) como argumento de manera que los hilos t_Hora y t_Fecha utilicen la
implementación del método run en la clase Reloj.
Para que ambos hilos comience a ejecutarse hay que invocar al método start de
cada uno de la siguiente manera:
t_Hora.start();
t_Fecha.start();
Una vez hecho esto se ejecutará el método run, pero ¿cómo saber cuál es el hilo
que se está ejecutando actualmente?. Esto se describe en la próxima sección.
3. El Método run()
El método run se encarga de manejar las tareas de un objeto Runnable. Saber
qué proceso se está ejecutando actualmente se puede averiguar con la ayuda del método
de clase currentThread() por ejemplo:
if(Thread.currentThread() == t_Hora){
mostrarHora();
}
Hacer que la tarea se quede indefinidamente corriendo se puede hacer añadiendo
un ciclo infinito:
while(true){
f(Thread.currentThread() == t_Fecha){
System.out.println("Proceso de fechas...");
}
Sin embargo este ciclo iría muy rápido y solamente interesa que la hora se
actualice cada segundo para lo cual se puede suspender al proceso durante un segundo
(1000 milésimas). El método que suspende al hilo tira una excepción
“InterruptedException” que hay que atrapar. Entonces el código de una aplicación que
muestra la hora y la fecha cada segundo puede quedar parecido a este:
import java.util.Calendar;
public class Hilos implements Runnable{
private Thread t_Fecha; // este hilo maneja la hora
private Thread t_Hora; // este hilo maneja la fecha
public Hilos(){
// Crear hilos...
t_Fecha = new Thread(this);
t_Hora = new Thread(this);
// Ponerlos a correr
t_Fecha.start();
t_Hora.start();
}
/** Ejecución de los hilos */
public void run(){
try{
while(true){
// indefinidamente haga…
if(Thread.currentThread() == t_Fecha){
// Si la tarea actual es para mostrar fecha…
System.out.println("Proceso de fechas...");
//dormir 1000 milésimas
t_Fecha.sleep(1000);
}
else{
//
System.out.println("Proceso de horas...");
t_Fecha.sleep(1000);
}
}
}
catch(InterruptedException ex){
// atrapar cualquier excepción que haya podido ocurrir
// mientras se suspendía el proceso.
}
}
public static void main(String args[]){
new Hilos();
}
}