The Java Memory Model (JMM) defines how threads interact with memory in Java. It specifies how variables are stored in memory and how threads access and modify those variables in a multi-threaded environment.
Why Java Memory Model is Needed
Modern CPUs use caching and reordering optimizations. Without a memory model, different threads might see inconsistent data. JMM ensures predictable behavior in concurrent programs.
Main Components of JMM
- Main Memory
- Thread Working Memory
Main Memory
Stores all shared variables. Every thread reads and writes shared data from main memory.
Thread Working Memory
Each thread has its own local working memory where it keeps copies of variables from main memory.
Example of Visibility Problem
class SharedData {
boolean flag = false;
void writer(){
flag = true;
}
void reader(){
while(!flag){
// may loop forever
}
System.out.println("Flag changed");
}
}
Solution Using volatile
class SharedData {
volatile boolean flag = false;
void writer(){
flag = true;
}
void reader(){
while(!flag){
}
System.out.println("Flag changed");
}
}
Key Concepts in Java Memory Model
1. Visibility
When one thread updates a variable, other threads should see the updated value.
2. Atomicity
An operation that executes completely or not at all.
Example:
AtomicInteger counter = new AtomicInteger();
counter.incrementAndGet();
3. Ordering
JVM and CPU may reorder instructions for performance. JMM defines rules to maintain correct execution order.
Happens-Before Relationship
Happens-before guarantees that memory writes by one thread are visible to another thread.
Examples:
- Thread start()
- Thread join()
- Volatile variable write/read
- Lock and unlock operations
Real World Example
Consider a microservice updating configuration settings shared across threads. Without proper synchronization, some threads may see outdated values.
Solution:
- Use volatile variables
- Use synchronized blocks
- Use concurrent collections
Quick Summary
- JMM defines how threads access shared memory
- Ensures visibility, ordering, and atomicity
- Threads use local working memory
- volatile ensures visibility
- synchronized ensures visibility and ordering
- Happens-before rule guarantees memory consistency
0 comments