When exactly do you use the volatile keyword in Java?
Interview Questions practice on Codemia
Over 8,000 real interview questions from top companies, searchable by company and role.
When working with Java, understanding concurrency is crucial, especially when dealing with the subtleties of the Java Memory Model (JMM). One fundamental element in this domain is the `volatile` keyword. In this article, we'll delve into the detailed application, purpose, and limitations of `volatile` in Java.
Introduction to `volatile`
The `volatile` keyword in Java is a variable modifier used to ensure that updates to a variable are propagated predictably across threads. When we declare a variable as `volatile`, the Java Memory Model ensures a few specific behaviors to aid with visibility and ordering in multi-threaded contexts.
Memory Consistency Issue
In Java, each thread has its own stack and, at times, a copy of the variables used in the method it is currently executing. The `volatile` keyword ensures that changes to the variable are immediately reflected in the main memory, visible to all threads. Without `volatile`, threads might cache variables, leading to stale data.
How the `volatile` Keyword Works
- Visibility: Using `volatile` guarantees that a read of a volatile variable sees the most recent write by any thread.
- Ordering: In practice, `volatile` establishes a happens-before relationship, enforcing any write to the volatile variable to be visible to subsequent reads of that variable.
However, note that `volatile` does not inherently provide atomicity or mutual exclusion.
Example Without `volatile`
Consider a scenario without `volatile`:
- Atomicity: Operations like incrementing a `volatile` variable are not atomic. Use `AtomicInteger` or `synchronized` for compound actions.
- Complex Synchronization: While `volatile` handles visibility and ordering, it can't handle complex synchronization scenarios. For such requirements, consider using locks (`synchronized`, `Lock`, etc.).
- Simple Flags: Ideal for status or boolean flags.
- Always Use Proper Synchronization: For read-modify-write actions (like increment or decrement), `volatile` is not a replacement for synchronization.
- Complex Data Structures: For Lists, Maps, or any data structures requiring atomic operations or complex mutations, `volatile` isn't suitable.
- Thread Safety Required: If multiple threads read and write, and atomicity is essential.
Related reading
- When is a condition variable needed, isn''t a mutex enough?
- When is a thread_local global variable initialized?
- When is ReaderWriterLockSlim better than a simple lock?
- When is ReaderWriterLockSlim better than a simple lock?
- When exactly is it leak safe to use (anonymous) inner classes?
- When exactly is it leak safe to use anonymous inner classes?
- When is too much async and await? Should all methods return Task?
- When might 2 phase commit not make progress?

OOD Fundamentals
Master object-oriented design from first principles, SOLID, design patterns, and classic interview problems with hands-on coding.
View the courseTrack what you have practised
A free account saves your progress, solutions and study plan across every problem on Codemia.
Interview Questions practice on Codemia
Over 8,000 real interview questions from top companies, searchable by company and role.