Concurrencia vs Paralelismo y el JMM (Stack vs Heap)
Concurrencia es gestionar múltiples tareas intercalando tiempo. Paralelismo es ejecutar tareas simultáneamente en distintos núcleos físicos. En el JMM cada hilo tiene su Stack privado, pero comparten el Heap.
class Contador { count = 42; } Anatomía de una Condición de Carrera: count++
count++ parece una sola instrucción pero en bytecode son 3 pasos no atómicos: ILOAD (leer), IADD (incrementar) e ISTORE (escribir).
El Cerrojo Intrínseco (synchronized) vs Atómicos Hardware (CAS)
synchronized suspende hilos en el monitor del sistema operativo (pesado). AtomicInteger usa Compare-And-Swap del CPU sin bloquear (lock-free).
Un hilo adquiere el cerrojo del monitor. Los demás pasan a estado BLOCKED esperando que se libere la llave.
public synchronized void incrementar() {
count++; // Protegido por Monitor
} Compara el valor esperado con la memoria. Si coincide, intercambia en 1 ciclo de hardware; si no, reintenta sin suspenderse.
private AtomicInteger count = new AtomicInteger();
// Sin locks: lock-free hardware atomic
count.incrementAndGet(); El Peligro del Deadlock y las Reglas de Prevención
Un Deadlock ocurre cuando dos o más hilos quedan congelados eternamente esperando recursos retenidos mutuamente. Se previene imponiendo un orden canónico de adquisición.
De Platform Threads a Pools y Virtual Threads (Project Loom)
1 hilo tradicional del SO pesa ~1 MB de stack y es costoso de crear. Los Virtual Threads de Java 21 son ultraligeros (~1 KB) y gestionados íntegramente por la JVM.
1 Hilo Java = 1 Hilo pesado del kernel del SO. Bloquearse en I/O suspende el hilo nativo.
Millones de hilos virtuales montados dinámicamente sobre pocos Carrier Threads. Si hay I/O, el virtual thread se desmonta sin frenar el CPU.
// 1 millón de hilos concurrentes sin colapsar la máquina:
try (var executor = Executors.newVirtualThreadPerTaskExecutor()) {
IntStream.range(0, 10_000).forEach(i -> {
executor.submit(() -> {
Thread.sleep(1000); // Se desmonta de la CPU durante el sleep
return i;
});
});
} // AutoCloseable espera a que todos terminen