Apuntes

Anuncio
Universidad Autónoma de Baja California
Facultad de Ingeniería
Apuntes de Programación Orientada a Objetos I
Hilos
Hasta el momento los programas que se han estado manejando en el curso han
sido secuenciales. Esto es, inician en un punto y continuan su ejecución de
manera predecible y en secuencia hasta el final. En un momento dado, solo se
esta ejecutando una parte del programa. Se puede decir que un programa con
los que se han estado trabajando tiene solo un hilo de ejecución.
El lenguaje Java permite escribir programas que al ejecutarse tengan mas de un
hilo de ejecución. Esto es, varias secciones del programa se encontrarán en
ejecución en un momento dado. Por supuesto que se debe recordar que al
tener solo una unidad de procesamiento o microprocesador, en realidad solo se
ejecutará una cosa a la vez. Sin embargo, al trabajar con hilos, se puede pensar
que en un momento habra varios hilos activos y trabajando.
Básicamente un hilo es un proceso ligero que solo puede ejecutarse dentro del
contexto de otro proceso que será el programa principal. Esto es, no puede
existir unicamente un hilo que se vaya a ejecutar, sino que un hilo solo puede
existir si se encuentra ligado a un programa ya que este último se encarga de
obtener los recursos necesarios para trabajar dentro del entorno de ejecución.
Caso de Estudio Timer
Java provee la clase Timer que trabaja conjuntamente con TimerTask para
calendarizar eventos que ocurran en sincronía con un reloj. La clase
java.util.Timer trabaja internamente con hilos de ejecución. El programa del
Listado 1 muestra como se puede calendarizar una tarea para que ésta se
ejecute una vez que hayan pasado 5 segundos. La primer sección iluminada
muestra como se crea un Timer y se programa un evento. La segunda sección
muestra que la clase RemindTask se deriva de TimerTask que a su vez
implanta al interfaz Runnable y además se sobrecarga el método run().
1 de 6
Elaborado por: M.C. Cecilia M. Curlango Rosas
Universidad Autónoma de Baja California
Facultad de Ingeniería
Apuntes de Programación Orientada a Objetos I
import java.util.Timer;
import java.util.TimerTask;
public class Reminder {
Timer timer;
public Reminder(int seconds) {
timer = new Timer();
timer.schedule(new RemindTask(), seconds*1000);
}
class RemindTask extends TimerTask {
public void run() {
System.out.println("Time's up!");
timer.cancel(); //Terminate the timer thread
}
}
public static void main(String args[]) {
System.out.println("About to schedule task.");
new Reminder(5);
System.out.println("Task scheduled.");
}
}
Listado 1 Ejemplo del uso de Timer
Como agregar hilos a una clase.
Para que una clase utilice hilos existen dos posibilidades. Una de ellas es que la
clase se derive de la clase java.lang.Thread y que sobrecargue el método run()
de ésta. El método run() es un método muy importante en hilos ya que éste es
el que se emplea para que indicarle a un hilo lo que debe hacer. El Listado 2
muestra como se puede crear hilos de esta forma. Mientras que el Listado 3
2 de 6
Elaborado por: M.C. Cecilia M. Curlango Rosas
Universidad Autónoma de Baja California
Facultad de Ingeniería
Apuntes de Programación Orientada a Objetos I
contiene un programa corto que emplea hilos y prueba la clase del listado
Listado 2.
public class SimpleThread extends Thread {
public SimpleThread(String str) {
super(str);
}
public void run() {
for (int i = 0; i < 10; i++) {
System.out.println(i + " " + getName());
try {
sleep((long)(Math.random() * 1000));
} catch (InterruptedException e) {}
}
System.out.println("DONE! " + getName());
}
}
Listado 2 Ejemplo de subclase de Thread y sobrecarga de run
public class TwoThreadsDemo {
public static void main (String[] args) {
new SimpleThread("Jamaica").start();
new SimpleThread("Fiji").start();
new SimpleThread("México").start();
System.out.println("Ahora me espero a la suerte.");
}
}
Listado 3 Ejemplo de uso de hilos.
En ocaciones el método de derivar de la clase Thread no puede emplearse
3 de 6
Elaborado por: M.C. Cecilia M. Curlango Rosas
Universidad Autónoma de Baja California
Facultad de Ingeniería
Apuntes de Programación Orientada a Objetos I
import java.awt.Graphics;
import java.util.*;
import java.text.DateFormat;
import java.applet.Applet;
public class Clock extends Applet implements Runnable {
private Thread clockThread = null;
public void start() {
if (clockThread == null) {
clockThread = new Thread(this, "Clock");
clockThread.start();
}
}
public void run() {
Thread myThread = Thread.currentThread();
while (clockThread == myThread) {
repaint();
try {
Thread.sleep(1000);
} catch (InterruptedException e){
// the VM doesn't want us to sleep anymore,
// so get back to work
}
}
}
public void paint(Graphics g) {
// get the time and convert it to a date
Calendar cal = Calendar.getInstance();
Date date = cal.getTime();
// format it and display it
DateFormat dateFormatter = DateFormat.getTimeInstance();
g.drawString(dateFormatter.format(date), 5, 10);
}
// overrides Applet's stop method, not Thread's
public void stop() {
clockThread = null;
}
}
4 de 6
Elaborado por: M.C. Cecilia M. Curlango Rosas
Universidad Autónoma de Baja California
Facultad de Ingeniería
Apuntes de Programación Orientada a Objetos I
debido a la restricción de Java en cuanto a la herencia múltiple. Un ejemplo de
esto sería en el caso de trabajar con applets ya que estos deben de derivarse
de la clase Applet para poder trabajar. Una alternativa para este tipo de casos el
de implantar la interfaz Runnable y a su vez definir un método run() apropiado
para la aplicación. El Listado 4 muestra como puede hacerse esto.
El ciclo de vida de un hilo
La vida de un hilo inicia con el método start(). Este es el unico método que
puede llamarse cuando recien se acaba de crear un hilo. Si se llama algún otro
método del hilo, se provocará una excepción ya que aun no le han sido
asignados recursos. Este método crear los recursos del sistema que se
requieren para el hilo, lo programa para ejecución y finalmente realiza una
llamada al método run() del hilo.
El método run() define las operaciones que deberán realizarse por el hilo
cuando éste se ejecute. Un hilo podrá entrar en estado de no ejecución cuando
ocurra uno de los siguientes eventos:
•Se
ejecute su propio método sleep()
•El
hilo ejecute el método wait() para esperar que se cumpla una condición
•El
hilo esta bloqueado en espera de una entrada o una salida.
Para detener o terminar la ejecución de un hilo puede simplemente terminarse
la ejecución del método run. Tambien el recolector de basura se puede
encargar de descartar un hilo una vez que ya no exista ninguna referencia a el.
Métodos para el control de Hilos
start() Inicia la ejecución de un hilo que acaba de crearse.
stop() Detiene y mata a un hilo.
sleep(int t) suspende un hilo durante t milisegundos.
yield() cede su turno de ejecución a otro hilo.
5 de 6
Elaborado por: M.C. Cecilia M. Curlango Rosas
Universidad Autónoma de Baja California
Facultad de Ingeniería
Apuntes de Programación Orientada a Objetos I
resume() desbloquea un hilo y hace que este listo para ejecutarse en cuanto
sea su turno.
destroy() mata a un hilo.
run() ejecuta las operciones que deberá realizar el hilo.
6 de 6
Elaborado por: M.C. Cecilia M. Curlango Rosas
Descargar