03/03/2023
Este artículo explora la creación de aplicaciones Java que utilizan hilos para realizar tareas en segundo plano, mejorando la capacidad de respuesta de la interfaz gráfica de usuario (GUI). Aprenderemos cómo declarar e implementar hilos en Java, utilizando tanto la clase Thread
como la interfaz Runnable
, y cómo integrarlos con una GUI para lograr una programación multihilo eficiente.

Declaración de Hilos en Java
Los hilos, también conocidos como subprocesos, son una característica fundamental de Java que permite la ejecución simultánea de múltiples partes de un programa. Cada parte se denomina hilo, y estos actúan como procesos livianos dentro de un proceso más grande. La programación multihilo en Java se basa en la API de concurrencia, que provee clases y herramientas para crear y gestionar hilos de manera eficiente.
Ciclo de Vida de un Hilo
Un hilo en Java atraviesa varias etapas en su ciclo de vida:
- Nuevo: El hilo se crea pero aún no se inicia.
- Ejecutable: El hilo está listo para ejecutarse, esperando su turno en el planificador del sistema operativo.
- En espera: El hilo está bloqueado, esperando un evento o recurso.
- Espera cronometrada: El hilo está bloqueado por un tiempo específico.
- Terminado (muerto): El hilo ha completado su ejecución.
Prioridades de Hilos
Cada hilo en Java tiene una prioridad, que influye en el orden en que el sistema operativo programa su ejecución. Las prioridades van de MIN_PRIORITY
(1) a MAX_PRIORITY
(10), con NORM_PRIORITY
(5) como valor predeterminado. Los hilos con mayor prioridad tienen preferencia, pero esto no garantiza un orden de ejecución específico y depende de la plataforma.
Creación de un Hilo
Existen dos maneras principales de crear un hilo en Java:
- Extendiendo la clase Thread: Se crea una subclase de
Thread
y se sobreescribe el métodorun()
, que contiene el código a ejecutar en el hilo. - Implementando la interfaz Runnable: Se crea una clase que implementa la interfaz
Runnable
, también con un métodorun()
. Un objetoRunnable
se pasa al constructor deThread
para crear el hilo.
Ejemplo Extendiendo Thread:
public class MiHilo extends Thread { public void run() { System.out.println("Corriendo hilo..."); }}
Ejemplo Implementando Runnable:
public class MiHilo implements Runnable { public void run() { System.out.println("Mi hilo está corriendo..."); }}
Error común: Llamar a run()
en lugar de start()
. start()
inicia el hilo; run()
ejecuta el código en el hilo actual.
Métodos de Hilos
La clase Thread
ofrece varios métodos útiles, como sleep()
para pausar la ejecución, join()
para esperar a que un hilo termine, e interrupt()
para interrumpir un hilo.
Integración con GUI
Para integrar hilos con una interfaz gráfica de usuario en Java (por ejemplo, usando Swing o JavaFX), es crucial tener en cuenta que los componentes GUI deben ser actualizados solo desde el hilo de eventos (Event Dispatch Thread o EDT). Actualizarlos desde otros hilos puede provocar excepciones y comportamiento impredecible.
Para actualizar la GUI desde un hilo en segundo plano, se utiliza SwingUtilities.invokeLater()
(Swing) o métodos similares en JavaFX. Este método coloca un código en la cola de eventos del EDT, garantizando que la actualización se realice de forma segura.
Ejemplo (Swing):
SwingUtilities.invokeLater(new Runnable() { public void run() { // Actualizar componentes GUI aquí miEtiqueta.setText("Hilo completado"); }});
Manejo de la Concurrencia
La programación multihilo introduce desafíos en el manejo de la concurrencia. Es fundamental evitar condiciones de carrera y otros problemas mediante el uso de mecanismos de sincronización:
- synchronized: Bloquea un bloque de código o un método para que solo un hilo pueda acceder a él a la vez.
- ReentrantLock: Proporciona un control más fino sobre la sincronización que
synchronized
. - Tipos atómicos (AtomicInteger, AtomicBoolean, etc.): Ofrecen operaciones atómicas sobre variables, evitando la necesidad de sincronización explícita en ciertos casos.
- ConcurrentHashMap, ConcurrentLinkedQueue, etc.: Colecciones concurrentes diseñadas para un acceso seguro desde múltiples hilos.
Ejemplos Avanzados
Se pueden crear ejemplos más complejos que involucren la comunicación entre hilos, el uso de pools de hilos ( ExecutorService
) para administrar un conjunto de hilos reutilizables, y el manejo de excepciones en entornos multihilo.
Conclusión
La programación multihilo en Java, combinada con una interfaz gráfica, permite crear aplicaciones más eficientes y con mejor capacidad de respuesta. Sin embargo, es esencial comprender los conceptos de concurrencia y utilizar las herramientas de sincronización apropiadas para evitar problemas y garantizar la estabilidad de la aplicación. El uso de SwingUtilities.invokeLater()
o su equivalente en JavaFX es crucial para actualizar la GUI de forma segura desde hilos secundarios.
Consultas Habituales:
- ¿Cómo evitar deadlocks (bloqueos) en Java?
- ¿Cuál es la mejor manera de sincronizar el acceso a recursos compartidos?
- ¿Cómo manejar excepciones en un entorno multihilo?
- ¿Qué son los thread pools y cómo se utilizan?
Tabla Comparativa: Métodos de Creación de Hilos
Método | Ventajas | Desventajas |
---|---|---|
Extendiendo Thread | Simple para tareas sencillas | Menos flexible para tareas complejas |
Implementando Runnable | Más flexible, permite composición de tareas | Requiere más código |