Why Thread B doesn't see what Thread A just wrote.
Modern CPUs are incredibly fast, but Main Memory (RAM) is slow. To speed things up, every CPU Core has its own private L1/L2 Cache. If Thread A (on Core 1) changes a variable, it writes it to its private cache. If Thread B (on Core 2) reads that variable a millisecond later, it might read the old value from its private cache, completely unaware of Thread A's change! This is a Memory Visibility bug, often resulting in infinite loops.
To fix visibility issues, you must tell the compiler and CPU: "Do not cache this variable!" In Java/C#, you use the volatile keyword. This inserts a hardware Memory Barrier, forcing the CPU to flush its cache and write/read directly to Main Memory for that variable.
# THE BUG (Infinite Loop)
keep_running = True
# Thread B runs this:
while keep_running: # Core 2 caches this as True forever!
do_work()
# Thread A runs this:
keep_running = False # Core 1 writes to L1 Cache, but Core 2 never sees it.
# THE FIX (Java example)
# 'volatile' guarantees cross-thread visibility.
private volatile boolean keepRunning = true;
Using volatile (or atomics/locks which inherently provide memory visibility guarantees) slows down the CPU because it bypasses the ultra-fast L1 cache and hits the slower Main Memory bus. Only use it when absolutely necessary for cross-thread coordination.
count++ on a `volatile` integer is still broken! If you need both visibility AND safe mutation, use a Lock or an Atomic.