- New (Nuevo). Es el estado cuando se crea un objeto hilo con el operador new. En este estado el hilo aún no se ejecuta; es decir, el programa no ha comenzado la ejecución del código del método run() del hilo.
- Runnable (Ejecutable). Cuando se invoca al método start(), el hilo pasa a este estado. El sistema operativo tiene que asignar tiempo de CPU al hilo para que se ejecute; por tanto, en este estado el hilo puede estar o no en ejecución.
- Dead (Muerto). Un hilo muere por varias razones:
- De muerte natural, porque el método run() finaliza con normalidad.
- Repentinamente debido a alguna excepción no capturada en el método run().
- Invocando al método stop(), pero este método está en desuso.
public class HiloEjemploDead extends Thread{
// Propiedades
private boolean stopHilo = false;
// Métodos
public void pararHilo(){
stopHilo = true;
}
public void run(){
while(!stopHilo){
System.out.println("En el
hilo");
}
}
// Main
public static void main(String[] args){
HiloEjemploDead h = new HiloEjemploDead();
h.start();
for (int i = 0; i < 100000; i++); // No hago nada
h.pararHilo();
}
}
- Blocked (Bloqueado). En este estado podría ejecutarse el hilo, pero hay algo que lo evita. Un hilo entra en estado bloquedo cuando ocurre una de las siguientes acciones:
- Alguien llama al método sleep() del hilo, es decir, se ha puesto a dormir.
- El hilo está esperando a que se complete una operación de entrada / salida.
- El hilo llama al método wait(). El hilo no se volverá ejecutable hasta que reciba los mensajes notify() o notifyAll().
- El hilo intenta bloquear un objeto que está actualmente bloqueado por otro hilo.
- Alguien llama al método suspend() del hilo. No se volverá a ejecutar de nuevo hasta que recia el mensaje resume().
Gestión de un hilo
Crear y arrancar
Para crear un hilo extendemos la clase Thread o
implementamos la interfaz Runnable.
// Se crea un hilo
MiHilo h = new
MiHilo(“Hilo 1”, 200);
// Se arranca el
hilo
h.start(); // Si la
clase extienda a Thread
new
Thread(h).start(); // Si implementa a Runnable
Lo que hace el método start()
es llamar al método run() del hilo
que es donde se colocan las acciones que queremos que haga el hilo, cuando
finalice el método finalizará también el hilo.
Suspensión
El método suspend()
permite detener la actividad del hilo durante un intervalo de tiempo
indeterminado.
Para volver a activar el hilo se necesita invocar al método resume().
El método suspend()
es un método obsoleto y tiende a no utilizarse porque puede producir
situaciones de interbloqueos. Por ejemplo, si un hilo está bloqueando un
recurso y este hilo se suspende, puede dar lugar a que otros hilos que esperaban
el recurso queden “congelados” ya que el hilo suspendido mantiene los recursos
bloqueados. Igualmente el método resume()
también está en desuso.
Para suspender de forma segura el hilo se debe introducir
dentro de este una variable, por ejemplo suspender, y comprobar su valor dentro
del método run().
class MyThread extends Thread{
// Propiedades
private SuspendRequestor
suspender = new SuspendRequestor();
// Métodos
public void requestSuspend(){
suspender.set(true);
}
public void requestResume(){
suspender.set(false);
}
public void run(){
try{
while(/* haya trabajo
por hacer */ true){
suspender.waitForResume(); // Realizar
el trabajo
}
}
catch(InterruptedException
exception){
e.printStackTrace();
}
}
}
class SuspendRequestor{
// Propiedades
private boolean suspendRequested;
// Métodos
public synchronized void set(boolean b){
suspendRequested = b;
notifyAll();
}
public synchronized void waitForResume() throws
InterruptedException{
while(suspendRequested)
wait();
}
}
Parada
Los métodos stop(),
suspend(), resume() y destroy() han
sido abolidos en Java 2 para reducir
la posibilidad de interbloqueo.
El método isAlive()
devuelve true si el hilo está vivo, es decir, ha llamado a su método run() y aún no ha terminado su ejecución
o no ha sido detenido con stop(); en
caso contrario devuelve false.
El método interrupt()
envía una petición de interrupción a un hilo. Si el hilo se encuentra bloqueado
por una llamada a sleep() o wait() se lanza una excepción InterruptedException.
El método isInterrupted()
devuelve true si el hilo ha sido interrumpid, en caso contrario devuelve false.
public class HiloEjemploInterrupt extends Thread{
public void run(){
try{
while (!isInterrupted()){
System.out.println("En el
hilo");
Thread.sleep(10);
}
}
catch(InterruptedException
e){
System.out.println("Ha ocurrido
una excepción");
}
System.out.println("Fin de
hilo");
}
public void interrumpir(){
interrupt();
}
public static void main(String[] args){
HiloEjemploInterrupt
h = new HiloEjemploInterrupt();
h.start();
try{
sleep(20);
}
catch(InterruptedException
e){
h.interrumpir();
}
}
}
El método join()
provoca que el hilo que hace la llamada espere la finalización de otros hilos.
public class HiloJoin extends Thread{
private int n;
public HiloJoin(String nom, int n){
super(nom);
this.n = n;
}
public void run(){
for (int i = 1; i <= n; i++){
System.out.println(getName() + ":" + i);
try{
sleep(1000);
}
catch(InterruptedException
ignore){}
}
System.out.println("Fin bucle
" +
getName());
}
}
public class EjemploJoin{
public static void main(String[] args){
HiloJoin h1 = new HiloJoin("Hilo 1", 2);
HiloJoin h2 = new HiloJoin("Hilo 2", 5);
HiloJoin h3 = new HiloJoin("Hilo 3", 7);
h1.start();
h2.start();
h3.start();
try{
h1.join();
h2.join();
h3.join();
}
catch(InterruptedException
e){}
System.out.println("Final del
programa");
}
}
0 comentarios:
Publicar un comentario