Skip to content

Latest commit

 

History

History
102 lines (79 loc) · 3.15 KB

File metadata and controls

102 lines (79 loc) · 3.15 KB

🚀 volatile Keyword in Java - Explained Simply!

The volatile keyword is used for variables to ensure that changes made by one thread are immediately visible to other threads. It helps prevent caching issues in multi-threaded environments.


1️⃣ Why Do We Need volatile?

In Java, multiple threads may cache a variable's value locally instead of reading it from the main memory. This can cause issues where one thread modifies a variable, but another thread doesn’t see the update.

🔹 volatile forces all threads to always read/write from main memory, ensuring visibility.


2️⃣ How volatile Works?

  • Ensures visibility of changes across threads.
  • Prevents caching of variables in CPU registers or thread-local memory.
  • Does NOT provide atomicity (cannot be used for operations like count++).

3️⃣ Example Without volatile (Wrong Behavior)

class Example {
    private static boolean flag = false;

    public static void main(String[] args) throws InterruptedException {
        Thread thread1 = new Thread(() -> {
            while (!flag) {  // ❌ Might be stuck in an infinite loop
            }
            System.out.println("Flag changed! Exiting loop...");
        });

        thread1.start();
        Thread.sleep(2000);
        flag = true;  // Updated by main thread
    }
}

💡 Problem?
Thread1 might not see the updated flag = true because it caches the value instead of checking main memory.


4️⃣ Fix Using volatile

class Example {
    private static volatile boolean flag = false;  // ✅ Ensures visibility

    public static void main(String[] args) throws InterruptedException {
        Thread thread1 = new Thread(() -> {
            while (!flag) {  // ✅ Will exit when flag is changed
            }
            System.out.println("Flag changed! Exiting loop...");
        });

        thread1.start();
        Thread.sleep(2000);
        flag = true;  // ✅ Immediately visible to thread1
    }
}

Now, thread1 sees the updated value immediately!


5️⃣ What volatile Cannot Do?

🚨 volatile does NOT ensure atomicity!

class Example {
    private volatile int count = 0;

    public void increment() {
        count++;  // ❌ Not atomic (read → modify → write)
    }
}

👉 Fix: Use synchronized instead:

class Example {
    private int count = 0;

    public synchronized void increment() {  // ✅ Ensures atomicity
        count++;
    }
}

6️⃣ When to Use volatile?

✅ When one thread writes, and multiple threads read.
✅ For flags (e.g., boolean running = true).
✅ When avoiding caching issues in multi-threading.

Do NOT use for counters (++ operations) – use synchronized or AtomicInteger instead.


🚀 TL;DR

  • volatile ensures visibility, prevents caching, but does NOT ensure atomicity.
  • Use it for simple status flags, but not for operations like count++.
  • If multiple threads modify shared data, use synchronized or AtomicInteger.