Você está na página 1de 5

1

Estado de un Hilo
Un hilo puede estar en uno de cuatro estados, cuando acabas de crearlo es un hilo nuevo
pero que no est en ejecucin ni est compitiendo por recursos del CPU, el siguiente estado
se denomina ejecutable, no en ejecucin, ejecutable indica que el hilo est compitiendo por
el CPU contra los otros hilos activos, solamente un hilo estar en ejecucin pero puede
haber muchos hilos en estado ejecutable que en cualquier momento pueden tomar posesin
del CPU, el tercer estado posible es detenido, ah simplemente el hilo no est compitiendo
por el CPU y esto lo podamos ver en el ejemplo pasado cuando ejecutbamos el mtodo
sleep y por ltimo el estado muerto, esto sucede cuando el hilo termina de ejecutar el
mtodo run.

En la figura puedes ver grficamente los cuatro estados y la manera de irse a cada uno de
ellos. El estado nuevo es cuando creas una instancia o un ejemplar de la clase Thread o de
alguna clase que extienda a Thread. Para que el hilo que creaste pase a estado ejecutable
necesitas llamar al mtodo start y el hilo estar en estado ejecutable que es compitiendo por
el CPU, hasta que sucedan algunas cosas, por un lado si mandas llamar al mtodo sleep
automticamente se ir al estado de detenido, cuando sale de este estado de detenido es
cuando hayan transcurrido la cantidad de milisegundos que especificaste en el mtodo sleep
en ese momento el hilo vuelve a ser ejecutable, es decir sigue compitiendo por el CPU con
los otros hilos activos, adems si llamas al mtodo wait se ir a estado de detenido y saldr
de este si ejecutas notify o notifyAll (esto no lo cubriremos en esta leccin), otra causa es
que el hilo haga una operacin de entrada-salida en ese momento se bloquea hasta que se
complete la operacin de entrada salida y por ltimo es llamar al mtodo suspend en ese
momento el hilo se va a estado de detenido y se queda ah hasta que se haga una llamada
al mtodo resume stos dos mtodos estn puestos en cursivas porque estn desaprobados,
es decir, no es recomendado su uso, la especificacin tcnica del por qu est fuera de los
alcances de este curso pero simplemente es necesario tener en cuenta que la utilizacin de
estos dos mtodos est desaprobada y no es conveniente hacerla.
El cuarto estado, cuando nuestro hilo se muere, llegamos a l ejecutando el mtodo run y
terminando su ejecucin, la otra causa puede ser que ejecutemos el mtodo stop pero este
mtodo tambin est desaprobado as es que no lo utilizaremos, entonces la manera de
terminar con nuestros hilos o matarlos es, simplemente que termine la ejecucin del mtodo
run en forma natural.
2
En los dos ejemplos anteriores nuestro mtodo run era simplemente un for que se
ejecutaba 10 veces, al terminar la ejecucin del run automticamente el hilo se mora. Y por
ltimo, cuando se est en estado ejecutable y se ejecuta el mtodo yield el hilo cede el
CPU a algn hilo de igual prioridad y comienza a competir por el CPU con los otros hilos,
entonces el hecho de llamar yield es simplemente dar la posibilidad a que otros hilos de
igual prioridad puedan ejecutarse y que un hilo no adquiera el CPU por tiempo indefinido.
new Tread (...)
- Creado, pero todava no comienza ejecucin
start ( )
- crea los recursos necesarios para su ejecucin, lo deja listo para que la mquina
virtual lo ponga a correr llamando al mtodo run (), compite por los recursos del
sistema.
Bloqueado por I/O, sleep () o wait ()
- La mquina virtual puede seleccionar otro hilo para ejecucin, para salir de este
estado la accin debe de corresponder la accin que la bloque.
Muerto
- Termin run (), una vez muerto un hilo no puede volver a ejecucin
Resumiendo, tenemos cuatro estados posibles de un hilo, nuevo, recin creado pero no
comienza su ejecucin despus de ejecutar start se crean todos los recursos necesarios para
hacer la ejecucin, ejecutable comienza a competir por el CPU con otros hilos, tercer
estado, detenido llegamos a l cuando el hilo se bloquea con una operacin de entrada
salida se invoca al mtodo sleep o el mtodo wait en ese momento la mquina virtual
selecciona otro hilo para ejecutarlo y por ltimo el estado muerto que para nosotros
simplemente ser el trmino de la ejecucin del mtodo run, es importante saber que una
vez que un hilo est muerto no se puede volver a ejecutar, es decir no puede mandar llamar
start otra vez. Qu es lo que tienes que hacer?, es crear otra instancia de tu clase para que
se cree un nuevo hilo.

Ejemplo
Veamos un ejemplo un poco ms entretenido, en este caso ser un applet, el archivo fuente
es Hilos3.java, tambin tienes un archivo llamado hilos3.html que puedes abrir desde un
browser para ver la ejecucin.
Antes de comenzar a hablar de los componentes de este applet y como maneja hilos,
veamos como es la ejecucin en pantalla, lo que vers es tres contadores que irn
desplegando el valor de cada uno a velocidades diferentes, adems en el rengln inferior ves
tres botones con los cuales puedes parar el conteo de cada uno de los contadores que
mencionamos, lo importante aqu es que sern tres contadores que se ejecutarn en forma
simultnea y contarn a diferente velocidad, entonces podrs hacer una pausa y cargar en el
browser la pgina hilos3.html, ver la ejecucin, jugar un momento con el applet y despus
volver a la leccin donde continuaremos explicando la programacin de este applet. En la
filmina lo primero que hacemos es el desplegado grfico de nuestro applet, tenemos 3
botones cuya etiqueta es para el 1, para el 2 y para el 3 y tenemos tres campos de texto
cuyo valor inicial es el valor 0. Adems tenemos tres objetos de la clase Cuenta que es
realmente un hilo que es el que ir desplegando a diferentes velocidades cada uno de los
contadores. En el mtodo init establecemos el layout a un GridLayout de dos renglones y
tres columnas agregamos los 6 componentes grficos y sin olvidar el detalle de hacer que
3
los botones respondan a eventos registrando el escuchador que en este caso es el applet con
cada uno de los botones que dispararn los eventos de accin.
import java.awt.*;
import java.applet.*;
import java.awt.event.*;

public class Hilos3 extends Applet implements ActionListener{
Button boton1 = new Button("Para el 1");
Button boton2 = new Button("Para el 2");
Button boton3 = new Button("Para el 3");
TextField cuenta1 = new TextField("0");
TextField cuenta2 = new TextField("0");
TextField cuenta3 = new TextField("0");
Cuenta t1, t2, t3;

public void init(){
setLayout(new GridLayout(2,3));
add(cuenta1);
add(cuenta2);
add(cuenta3);
add(boton1);
add(boton2);
add(boton3);
boton1.addActionListener(this);
boton2.addActionListener(this);
boton3.addActionListener(this);
}

Continuando con nuestro applet vemos que en el mtodo start, este mtodo start es del
applet, no tiene absolutamente nada que ver con la llamada start de un hilo, en el mtodo
start creamos los tres hilos, t1, t2 y t3 que son de la clase Cuenta, que son como puedes ver
el constructor de Cuenta, requiere dos parmetros, el primero es la cantidad de
milisegundos entre cada conteo, t1 dejar pasar medio segundo t2 un segundo completo y
t3, dos segundos.
El segundo parmetro es el campo de texto donde se ir desplegando el conteo cada hilo
tendr su propio campo de texto, en la parte final de start tenemos que arrancar los hilos
correspondientes, ya los creamos pero como sabemos eso no es suficiente, tenemos que
arrancarlos.
En el mtodo stop lo que hacemos es paramos el conteo, es decir matamos al hilo,
normalmente esto lo hacemos con una variable de control booleana como vers en la
siguiente filmina, nuestro mtodo run ser controlado por esta variable booleana en el
4
momento que sea falsa, se terminar la ejecucin del ciclo y por lo tanto se terminar la
ejecucin del run y el hilo morir. Y por ltimo simplemente identificamos en el mtodo
actionPerformed que botn ser presionado y simplemente hacemos la variable contando del
hilo correspondiente igual a falso para matar el hilo, entonces como puedes ver aqu lo
importante es la creacin de los tres hilos los dos parmetros que se manda a cada uno y
cmo podemos parar la ejecucin de los hilos.
Ahora veamos como est programada la clase Cuenta y si es realmente la clase que permite
ejecutar esto en forma simultnea, cada uno de los tres contadores.
public void start(){
t1 = new Cuenta(500,cuenta1);
t2 = new Cuenta(1000,cuenta2);
t3 = new Cuenta(2000,cuenta3);
t1.start(); t2.start();
t3.start();
}
public void stop(){
t1.contando = false;
t2.contando = false;
t3.contando = false;
}
public void actionPerformed(ActionEvent e){
if (e.getSource().equals(boton1))
t1.contando = false;
else if (e.getSource().equals(boton2))
t2.contando = false;
else if (e.getSource().equals(boton3))
t3.contando = false;
}
}
Nuestra clase Cuenta obviamente extiende a Thread, tenemos algunas variables de la clase
por un lado tenemos un deltaT que es de tipo long, que es el que determinar la velocidad
del conteo por otra parte tenemos una variable entera que es el nmero que llevar el
conteo en este caso se llama cuenta y es inicializada al valor de 0. Adems tenemos una
variable caja que ser un campo de texto, que no va a existir dentro de esta clase pero esa
es la variable que va a contener una referencia al campo de texto correspondiente en el
applet y por ltimo una variable booleana contando que me controlar hasta donde vive el
hilo. Despus puedes ver el constructor de la clase Cuenta que recibe dos parmetros que
ya mencionamos y que los guardamos en las variables de la clase Cuenta deltaT y caja. Esto
es importante, porque necesitamos una referencia al campo de texto correspondiente en el
applet para desplegar el conteo desde un objeto de la clase Cuenta sino, no podramos tener
acceso a los campos de texto del applet, necesitamos una referencia y esa referencia es la
que se manda como parmetro. Y por ltimo el mtodo run, que es el corazn de nuestro
hilo y de todos los hilos simplemente es un ciclo while mientras contando sea verdadera se
ir ejecutando, se incrementa la variable cuenta en uno y despus se despliega su valor en
el campo de texto correspondiente, acto seguido simplemente se manda llamar sleep por un
deltaT para parar el conteo y ese es todo nuestro ciclo. En el momento en que se sale del
ciclo en el campo de texto correspondiente se despliega el letrero: ya se muri, indicando
que el hilo ya est muerto, este es todo nuestro applet y si ya viste la ejecucin puedes ver
que los tres contadores, cuentan a diferente velocidad adems lo importante es que los tres
5
contadores son exactamente de la misma clase, simplemente las creas con diferente
parmetro, entonces en el momento de ejecutar este applet los que tu tienes es cuatro hilos
corriendo, el hilo donde corre el applet que es donde se despliegan los contadores y el que
controla los eventos de los botones y cada uno de los tres hilos que ejecuta el conteo y
actualiza su correspondiente campo de texto. Espero que con esto quede claro el concepto
de hilos y que veas que ventaja reporta. Este programa sera prcticamente imposible
realizarlo si es que no tuviramos el concepto de hilos.

class Cuenta extends Thread{
long deltaT;
int cuenta=0;
TextField caja;
boolean contando = true;

public Cuenta(long deltaT, TextField caja){
this.deltaT = deltaT;
this.caja = caja;
}

public void run(){
while(contando){
cuenta ++;
caja.setText(Intejer.toString(cuenta));
try{
sleep(deltaT);
}
}
caja.setText("Ya se muri);
}
}

Você também pode gostar