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:
- Nuevo (New): El hilo ha sido creado pero aún no ha comenzado a ejecutarse.
- Ejecutable (Runnable): El hilo está listo para ejecutarse y está esperando que el sistema operativo le asigne tiempo de CPU.
- En Ejecución (Running): El hilo está actualmente ejecutándose.
- Bloqueado (Blocked): El hilo está esperando para adquirir un monitor lock para entrar en una sección crítica.
- Esperando (Waiting): El hilo está esperando indefinidamente hasta que otro hilo lo despierte.
- Esperando con Tiempo Límite (Timed Waiting): El hilo está esperando por un tiempo específico.
- 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
-
Creación del Hilo:
HiloEjemplo hilo = new HiloEjemplo();
En este punto, el hilo está en el estado Nuevo.
-
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. -
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. -
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
-
Creación de Hilos: Se crean tres instancias de
MiHilo
. -
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. -
Estado de Espera con Tiempo Límite: Cada hilo duerme durante 2 segundos, entrando en el estado Timed Waiting.
-
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
- Introducción a Java
- Configuración del Entorno de Desarrollo
- Sintaxis y Estructura Básica
- Variables y Tipos de Datos
- Operadores
Módulo 2: Flujo de Control
Módulo 3: Programación Orientada a Objetos
- Introducción a la POO
- Clases y Objetos
- Métodos
- Constructores
- Herencia
- Polimorfismo
- Encapsulamiento
- Abstracción
Módulo 4: Programación Orientada a Objetos Avanzada
Módulo 5: Estructuras de Datos y Colecciones
Módulo 6: Manejo de Excepciones
- Introducción a las Excepciones
- Bloque Try-Catch
- Throw y Throws
- Excepciones Personalizadas
- Bloque Finally
Módulo 7: Entrada/Salida de Archivos
- Lectura de Archivos
- Escritura de Archivos
- Flujos de Archivos
- BufferedReader y BufferedWriter
- Serialización
Módulo 8: Multihilo y Concurrencia
- Introducción al Multihilo
- Creación de Hilos
- Ciclo de Vida de un Hilo
- Sincronización
- Utilidades de Concurrencia
Módulo 9: Redes
- Introducción a las Redes
- Sockets
- ServerSocket
- DatagramSocket y DatagramPacket
- URL y HttpURLConnection