Hilos (Threads) y concurrencia en Java
Ejecuta varias tareas a la vez con Thread, Runnable y ExecutorService. Con demos animadas de ejecución paralela y de condiciones de carrera.
Un hilo (thread) es una línea de ejecución independiente. Con varios hilos tu programa hace cosas «a la vez»: descargar mientras dibuja la interfaz, procesar varios ficheros en paralelo… A cambio, aparecen problemas nuevos cuando dos hilos tocan el mismo dato.
// 1. Runnable con lambda (lo más común)
Thread t = new Thread(() -> System.out.println("Hola desde " + Thread.currentThread().getName()));
t.start(); // arranca el hilo (NO usar run(), eso no crea hilo)
t.join(); // espera a que termine
Secuencial vs paralelo
Tres tareas que tardan 3, 2 y 1 segundos. En secuencial sumas los tiempos; con hilos, casi lo que tarde la más lenta.
Condición de carrera y synchronized
Dos hilos suman 1 a un contador 100 000 veces cada uno. El resultado debería ser
200 000. Sin protección, contador++ no es atómico (leer → sumar → guardar) y se pierden
incrementos. Con synchronized o AtomicInteger el resultado es correcto.
ExecutorService
Crear un Thread por tarea no escala. Un pool reutiliza un número fijo de hilos y tú
solo le vas dando trabajo.
ExecutorService pool = Executors.newFixedThreadPool(3);
for (int i = 1; i <= 8; i++) {
int tarea = i;
pool.submit(() -> System.out.println("Tarea " + tarea + " en " + Thread.currentThread().getName()));
}
pool.shutdown(); // no acepta más; termina las pendientes
Comprueba lo aprendido
contador++ sin sincronizar. El resultado…t.join() sirve para…