0
0
JavaConceptBeginner · 3 min read

What is volatile keyword in Java: Explanation and Example

In Java, the volatile keyword is used to mark a variable so that changes to it are immediately visible to all threads. It ensures that the variable's value is always read from and written to main memory, preventing threads from caching it locally.
⚙️

How It Works

Imagine you and your friend are sharing a notebook to write notes. If you both keep copies of the notebook at your desks, you might not see each other's updates right away. The volatile keyword in Java acts like a rule that says "always check the shared notebook directly" instead of looking at your own copy.

In technical terms, when a variable is declared volatile, every read of that variable will get the latest value from the main memory, and every write will be immediately saved to main memory. This prevents threads from using outdated cached values and ensures they see the most recent update.

This is important in multi-threaded programs where different threads might be working with the same variable. Without volatile, one thread might not see changes made by another thread right away, causing bugs.

💻

Example

This example shows two threads updating and reading a volatile variable. The reader thread sees the updated value immediately because of volatile.

java
public class VolatileExample {
    private static volatile boolean flag = false;

    public static void main(String[] args) throws InterruptedException {
        Thread writer = new Thread(() -> {
            try {
                Thread.sleep(1000); // wait 1 second
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
            }
            flag = true;
            System.out.println("Flag set to true by writer thread");
        });

        Thread reader = new Thread(() -> {
            System.out.println("Reader thread started, waiting for flag...");
            while (!flag) {
                // busy wait
            }
            System.out.println("Reader thread detected flag change!");
        });

        reader.start();
        writer.start();

        writer.join();
        reader.join();
    }
}
Output
Reader thread started, waiting for flag... Flag set to true by writer thread Reader thread detected flag change!
🎯

When to Use

Use volatile when you have a variable shared between threads and you want to make sure all threads see the latest value immediately. It is useful for simple flags or status indicators.

For example, it can be used to stop a thread by setting a volatile boolean flag from another thread. It is not suitable for complex operations like incrementing a counter because it does not provide atomicity.

In real-world cases, volatile helps avoid subtle bugs caused by threads working with stale data, especially in concurrent programming.

Key Points

  • Visibility: volatile ensures changes are visible to all threads immediately.
  • No caching: Threads do not cache volatile variables locally.
  • Not atomic: Operations like increment are not safe with volatile alone.
  • Simple synchronization: Useful for flags and status variables.

Key Takeaways

The volatile keyword ensures a variable's latest value is always read from main memory.
It guarantees visibility of changes across threads but does not make operations atomic.
Use volatile for simple flags or status indicators shared between threads.
Volatile prevents threads from caching variables locally, avoiding stale data bugs.
For complex synchronization, use other concurrency tools like synchronized or atomic classes.