If we don’t use volatile, worker Thread may never terminate
public class Volatile { // volatile is needed here private static volatile boolean stop = false; public static void main(String[] args) throws InterruptedException { Thread worker = new Thread(() -> { int i = 0; while (!stop) { i++; } System.out.println("Stopped at i = " + i); }); worker.start(); Thread.sleep(1000); stop = true; System.out.println("stop set to true"); }}
Double Thread Example
If we don’t use volatile then readerThread will never read latest value and while loop never terminates in readerThread
public class Volatile { // volatile is needed here private static boolean flag = false; public static void main(String[] args) { Thread writerThread = new Thread(() -> { try { Thread.sleep(2000); System.out.println("Flag to set"); flag = true; } catch (InterruptedException e) { Thread.currentThread().interrupt(); } }); Thread readerThread = new Thread(() -> { while (!flag) { // busy waiting } flag = false; System.out.println("Flag is unset finally!"); }); writerThread.start(); readerThread.start(); }}
Working (can be improved)
CPU stores the variable in cache, and sometimes after updating value in CPU cache, it does not immediately update the main memory (RAM) and also to other CPU cache
Hence other threads may not see the change instantaneously
volatile causes read and write to happen on main memory (RAM) directly instead of cache
Volatile variables are not cached in registers or in caches where they are hidden from other processors, so a read of a volatile variable always returns the most recent write by any thread