En este tema, exploraremos el ciclo de vida de un hilo en Java. Comprender cómo funcionan los hilos y sus estados es crucial para escribir programas concurrentes eficientes y libres de errores.

Estados de un Hilo

Un hilo en Java puede estar en uno de los siguientes estados:

  1. Nuevo (New): El hilo ha sido creado pero aún no ha comenzado a ejecutarse.
  2. Ejecutable (Runnable): El hilo está listo para ejecutarse y está esperando que el sistema operativo le asigne tiempo de CPU.
  3. En Ejecución (Running): El hilo está actualmente ejecutándose.
  4. Bloqueado (Blocked): El hilo está esperando para adquirir un monitor lock para entrar en una sección crítica.
  5. Esperando (Waiting): El hilo está esperando indefinidamente hasta que otro hilo lo despierte.
  6. Esperando con Tiempo Límite (Timed Waiting): El hilo está esperando por un tiempo específico.
  7. Terminado (Terminated): El hilo ha completado su ejecución.

Diagrama del Ciclo de Vida de un Hilo

+---------+       +-----------+       +-----------+       +-----------+
|  Nuevo  | ----> | Ejecutable| ----> | En Ejecución| ----> | Terminado |
+---------+       +-----------+       +-----------+       +-----------+
                     ^  |                |  ^                |
                     |  |                |  |                |
                     |  v                v  |                |
                 +-----------+       +-----------+       +-----------+
                 | Bloqueado |       | Esperando |       | Timed Waiting |
                 +-----------+       +-----------+       +-----------+

Ejemplo Práctico

Vamos a crear un ejemplo simple para ilustrar el ciclo de vida de un hilo en Java.

Código de Ejemplo

class HiloEjemplo extends Thread {
    @Override
    public void run() {
        System.out.println("Hilo en ejecución: " + Thread.currentThread().getName());
        try {
            // El hilo entra en estado de espera con tiempo límite
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("Hilo finalizado: " + Thread.currentThread().getName());
    }
}

public class CicloDeVidaHilo {
    public static void main(String[] args) {
        HiloEjemplo hilo = new HiloEjemplo();
        
        // Estado: Nuevo
        System.out.println("Estado del hilo después de la creación: " + hilo.getState());
        
        hilo.start();
        
        // Estado: Ejecutable
        System.out.println("Estado del hilo después de llamar a start(): " + hilo.getState());
        
        try {
            // Esperar a que el hilo termine
            hilo.join();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        
        // Estado: Terminado
        System.out.println("Estado del hilo después de la finalización: " + hilo.getState());
    }
}

Explicación del Código

  1. Creación del Hilo:

    HiloEjemplo hilo = new HiloEjemplo();
    

    En este punto, el hilo está en el estado Nuevo.

  2. Inicio del Hilo:

    hilo.start();
    

    Al llamar a start(), el hilo pasa al estado Ejecutable y luego al estado En Ejecución cuando el sistema operativo le asigna tiempo de CPU.

  3. Estado de Espera con Tiempo Límite:

    Thread.sleep(1000);
    

    Dentro del método run(), el hilo entra en el estado Timed Waiting durante 1 segundo.

  4. Finalización del Hilo:

    hilo.join();
    

    El método join() se utiliza para esperar a que el hilo termine su ejecución. Una vez que el hilo completa su ejecución, pasa al estado Terminado.

Ejercicio Práctico

Ejercicio

Crea un programa que inicie tres hilos. Cada hilo debe imprimir su nombre y luego dormir durante 2 segundos antes de finalizar. Imprime el estado de cada hilo en diferentes puntos del ciclo de vida.

Solución

class MiHilo extends Thread {
    @Override
    public void run() {
        System.out.println("Hilo en ejecución: " + Thread.currentThread().getName());
        try {
            Thread.sleep(2000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("Hilo finalizado: " + Thread.currentThread().getName());
    }
}

public class CicloDeVidaHilos {
    public static void main(String[] args) {
        MiHilo hilo1 = new MiHilo();
        MiHilo hilo2 = new MiHilo();
        MiHilo hilo3 = new MiHilo();
        
        System.out.println("Estado del hilo1 después de la creación: " + hilo1.getState());
        System.out.println("Estado del hilo2 después de la creación: " + hilo2.getState());
        System.out.println("Estado del hilo3 después de la creación: " + hilo3.getState());
        
        hilo1.start();
        hilo2.start();
        hilo3.start();
        
        System.out.println("Estado del hilo1 después de llamar a start(): " + hilo1.getState());
        System.out.println("Estado del hilo2 después de llamar a start(): " + hilo2.getState());
        System.out.println("Estado del hilo3 después de llamar a start(): " + hilo3.getState());
        
        try {
            hilo1.join();
            hilo2.join();
            hilo3.join();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        
        System.out.println("Estado del hilo1 después de la finalización: " + hilo1.getState());
        System.out.println("Estado del hilo2 después de la finalización: " + hilo2.getState());
        System.out.println("Estado del hilo3 después de la finalización: " + hilo3.getState());
    }
}

Explicación de la Solución

  1. Creación de Hilos: Se crean tres instancias de MiHilo.

  2. Inicio de Hilos: Se llama al método start() en cada hilo, lo que los pone en el estado Ejecutable y luego en En Ejecución.

  3. Estado de Espera con Tiempo Límite: Cada hilo duerme durante 2 segundos, entrando en el estado Timed Waiting.

  4. Finalización de Hilos: Se utiliza join() para esperar a que cada hilo termine su ejecución, pasando al estado Terminado.

Conclusión

En esta lección, hemos aprendido sobre los diferentes estados de un hilo en Java y cómo un hilo transita entre estos estados durante su ciclo de vida. También hemos visto ejemplos prácticos y ejercicios para reforzar estos conceptos. Con esta comprensión, estarás mejor preparado para manejar la concurrencia y el multihilo en tus aplicaciones Java.

Curso de Programación en Java

Módulo 1: Introducción a Java

Módulo 2: Flujo de Control

Módulo 3: Programación Orientada a Objetos

Módulo 4: Programación Orientada a Objetos Avanzada

Módulo 5: Estructuras de Datos y Colecciones

Módulo 6: Manejo de Excepciones

Módulo 7: Entrada/Salida de Archivos

Módulo 8: Multihilo y Concurrencia

Módulo 9: Redes

Módulo 10: Temas Avanzados

Módulo 11: Frameworks y Librerías de Java

Módulo 12: Construcción de Aplicaciones del Mundo Real

© Copyright 2024. Todos los derechos reservados