Estados de un hilo

El ciclo de vida de un hilo en Java pasa por los siguientes estados:

Estado Descripción
New Estado inicial tras crear el objeto con new, antes de llamar a start()
Runnable Alcanzado al llamar a start(). El sistema operativo puede asignarle tiempo de CPU
Dead El hilo ha finalizado por conclusión normal de run(), excepción no capturada o llamada a stop() (obsoleto)
Blocked El hilo no se ejecuta porque está dormido (sleep()), esperando E/S, en wait(), intentando bloquear un recurso ocupado o suspendido

Creación y gestión de hilos

Los hilos se crean extendiendo Thread o implementando Runnable. Se arrancan con start(), que ejecuta el método run() en un hilo separado.

Métodos importantes:

Método Descripción
start() Inicia el hilo
join() Espera a que otro hilo finalice
interrupt() Solicita la interrupción del hilo
isInterrupted() Verifica si el hilo ha sido interrumpido
isAlive() Comprueba si el hilo sigue activo
sleep(ms) Pausa el hilo el número de milisegundos indicado

Ejemplo: parar un hilo de forma segura

public class HiloEjemploDead extends Thread {
    private boolean stopHilo = false;

    public void pararHilo() {
        stopHilo = true;
    }

    public void run() {
        while (!stopHilo) {
            System.out.println("En el hilo");
        }
    }

    public static void main(String[] args) {
        HiloEjemploDead h = new HiloEjemploDead();
        h.start();
        for (int i = 0; i < 100000; i++);
        h.pararHilo();
    }
}

Ejemplo: patrón de suspensión segura

class MyThread extends Thread {
    private SuspendRequestor suspender = new SuspendRequestor();

    public void requestSuspend() { suspender.set(true); }
    public void requestResume() { suspender.set(false); }

    public void run() {
        try {
            while (true) {
                suspender.waitForResume();
            }
        } catch (InterruptedException exception) {
            exception.printStackTrace();
        }
    }
}

class SuspendRequestor {
    private boolean suspendRequested;

    public synchronized void set(boolean b) {
        suspendRequested = b;
        notifyAll();
    }

    public synchronized void waitForResume() throws InterruptedException {
        while (suspendRequested)
            wait();
    }
}

Ejemplo: interrupción de un hilo

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 {
            Thread.sleep(20);
        } catch (InterruptedException e) {
            h.interrumpir();
        }
    }
}

Ejemplo: join — esperar a que terminen 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 {
                Thread.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");
    }
}

El método join() hace que el hilo principal espere a que h1, h2 y h3 terminen antes de imprimir el mensaje final.