Hardware-Level False Sharing in Java
You’ve optimized your algorithms, but your high-throughput service is still stalling. The culprit might be invisible at the code level: False Sharing.
1. The CPU Cache Line
Modern CPUs don't load individual bytes from RAM. They load data in 64-byte blocks called Cache Lines. If your thread updates a variable, the entire 64-byte line is marked as "invalid" across all other CPU cores.
2. The Conflict
Imagine two variables, and , living right next to each other in memory.
- Thread 1 updates .
- Thread 2 updates . Because they live on the same cache line, the CPU cores are constantly fighting over ownership of that line, even though the variables are unrelated. This is False Sharing.
3. The Solution: @Contended (Java 8+)
Java provides a built-in annotation to prevent this: .
- How it works: The JVM adds 128 bytes of empty space (padding) around the field, ensuring it sits on its own cache line.
4. Manual Padding
If you cannot use the annotation, you can add "Dummy" fields to your class:
public class MyCounter {
public volatile long counterA;
public long p1, p2, p3, p4, p5, p6, p7; // Padding
public volatile long counterB;
}
Summary
False Sharing is a "Ghost in the Machine" that can destroy multi-threaded performance. By respecting the 64-byte boundaries of the CPU, you build backend systems that truly leverage the power of multi-core hardware.
Build the Series: LMAX Disruptor: Ultra-High Performance Concurrency
