In Java, the volatile
keyword is used as a modifier for instance variables to indicate that their value may be modified by multiple threads concurrently. It ensures proper visibility and ordering of variable reads and writes in a multithreaded environment.
Key Aspects of the volatile
Keyword
1. Visibility Guarantee
- When a variable is declared
volatile
, any write to it by one thread is immediately visible to all other threads. - Without
volatile
, threads may cache variables locally, leading to stale data.
2. No Thread-Local Caching
- The JVM ensures that the value of a
volatile
variable is always read from the main memory, not from a thread's local cache.
3. Atomic Read and Write (but not Compound Operations)
- The
volatile
keyword guarantees that reads and writes are atomic. - However, compound actions like
count++
are not atomic and must be protected with synchronization or atomic classes.
4. Lightweight Alternative to Synchronization
- Unlike
synchronized
, volatile
does not involve locking, making it more lightweight and performant for simple read/write operations.
5. Use Cases
The volatile
keyword is suitable when:
- Only one thread modifies the variable, and others read it.
- There are no compound actions or multiple-variable dependencies.
- Visibility is the primary concern, not mutual exclusion.
Example:
java
class SharedResource {
private volatile boolean flag = false;
public void setFlagTrue() {
flag = true;
}
public boolean isFlagTrue() {
return flag;
}
}
In this example, the flag
variable is declared as volatile
so that when one thread sets it to true
, other threads can immediately see that change without delay.
Important Note:
While volatile
is useful for visibility in simple cases, it does not replace synchronized
or other thread-safety mechanisms for complex operations. For compound actions or managing consistency across multiple variables, consider using synchronization or classes from the java.util.concurrent
package like AtomicInteger
or ReentrantLock
.