El API de hilos nativos de Java se basa en la clase Thread y en la interfaz Runnable. Aquí aprenderás a crearlos de forma segura, conocer su ciclo de vida y usar las herramientas básicas para coordinarlos sin sorpresas.
run(): extiende Thread y coloca la lógica dentro del método run.start() vs run(): start() crea un hilo nuevo y luego invoca run() dentro de él; llamar a run() directamente ejecuta en el mismo hilo actual.NEW → RUNNABLE/RUNNING → BLOCKED (o WAITING/TIMED_WAITING) → TERMINATED.class TrabajoPesado extends Thread {
@Override
public void run() {
System.out.println("[Hilo] Iniciando");
try {
Thread.sleep(300); // Simula trabajo
} catch (InterruptedException e) {
System.out.println("[Hilo] Interrumpido");
Thread.currentThread().interrupt();
}
System.out.println("[Hilo] Terminando");
}
public static void main(String[] args) {
TrabajoPesado hilo = new TrabajoPesado();
hilo.start(); // Ejecuta en un hilo aparte
// hilo.run(); // Ejecutaría en el mismo hilo main
}
}
Runnable declara un solo método run(), compatible con expresiones lambda.Runnable y decides luego si ejecutarla en un Thread directo o en un Executor.public class DemoRunnable {
public static void main(String[] args) throws Exception {
Runnable tarea = () -> System.out.println("Hola desde " + Thread.currentThread().getName());
Thread hilo = new Thread(tarea, "worker-1");
hilo.start();
hilo.join(); // Espera a que termine
}
}
Thread.State)start().synchronized) para continuar.Object.wait(), join() sin timeout).sleep, wait(timeout), join(timeout)).run() o lanzó una excepción no manejada.Thread.sleep(): pausa actual sin liberar monitores; maneja InterruptedException y vuelve a marcar el hilo si abortas.Thread.yield(): sugerencia al planificador; no garantiza efecto.Thread.interrupt(): marca un hilo como interrumpido; las operaciones bloqueantes lanzan InterruptedException.join(): espera que otro hilo termine; usa timeouts para evitar bloqueos indefinidos y propaga InterruptedException correctamente.setPriority()): rara vez conviene cambiarlas; los sistemas modernos las ignoran o producen starvation (hilos de menor prioridad no avanzan) si se abusa.public class PararConInterrupcion implements Runnable {
@Override
public void run() {
while (!Thread.currentThread().isInterrupted()) {
try {
hacerTrabajo();
} catch (InterruptedException e) {
Thread.currentThread().interrupt(); // reestablece bandera
}
}
limpiarRecursos();
}
private void hacerTrabajo() throws InterruptedException {
Thread.sleep(100);
}
private void limpiarRecursos() {
System.out.println("Liberando recursos...");
}
}
Thread manualmenteExecutorService o frameworks reactivos.