Concurrency vs Parallelism and JMM (Stack vs Heap)
Concurrency is dealing with multiple things via time-slicing. Parallelism is doing multiple things at once on physical cores. In JMM each thread has a private Stack, sharing the common Heap.
class Contador { count = 42; } Anatomy of a Race Condition: count++
count++ looks like a single statement but in bytecode comprises 3 non-atomic steps: ILOAD (read), IADD (add) and ISTORE (write).
Intrinsic Lock (synchronized) vs Hardware Atomics (CAS)
synchronized parks threads using OS monitor locks (heavy). AtomicInteger relies on CPU Compare-And-Swap instructions without blocking (lock-free).
One thread acquires the object monitor lock. Competing threads enter BLOCKED state waiting for release.
public synchronized void incrementar() {
count++; // Protegido por Monitor
} Compares expected value against memory. If matched, swaps atomically in 1 hardware cycle; otherwise retries without parking.
private AtomicInteger count = new AtomicInteger();
// Sin locks: lock-free hardware atomic
count.incrementAndGet(); The Danger of Deadlock and Prevention Rules
A Deadlock occurs when two or more threads freeze permanently waiting for resources held by each other. Prevented by enforcing strict canonical lock ordering.
From Platform Threads to Pools and Virtual Threads (Project Loom)
A classic OS platform thread costs ~1 MB stack and heavy kernel overhead. Java 21 Virtual Threads are lightweight (~1 KB) managed purely by the JVM.
1 Java Thread = 1 heavyweight OS kernel thread. Blocking in I/O stalls native thread.
Millions of virtual threads mounted onto few carrier threads. On I/O block, it unmounts cleanly.
// 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