Threads and concurrency in Java
Run several tasks at once with Thread, Runnable and ExecutorService. With animated demos of parallel execution and race conditions.
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
Sequential vs parallel
Tres tareas que tardan 3, 2 y 1 segundos. En secuencial sumas los tiempos; con hilos, casi lo que tarde la más lenta.
Race condition and 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
Check what you've learned
contador++ sin sincronizar. El resultado…t.join() sirve para…