6 Uses of Volatile in Java

July 10, 2020 By RJ

The “volatile” modifier in Java indicates JVM that the threads accessing the variable should always get the data from “main memory“. The Thread should not cache the volatile variable.

This keyword is very rarely used keyword in Java. Yet we have to know the working and when we can use volatile modifier especially in multithreading. This is also an important concept when it comes to cracking JAVA interview for both freshers and experienced.

volatile
Syntax

Need for volatile

Memory Order

Caching and reordering are among those optimizations that may surprise us in concurrent contexts. Java and the JVM provide many ways to control memory order, and this keyword is one of them.

Shared Multiprocessor

Threads in processor are responsible for executing instruction in the program. As CPU is capable of carrying significant number of instructions its not ideal for processor to fetch the data from RAM always so the caching concept came into picture to improve this situation.
The below digram explains the memory hierarchy

If two threads are working on a shared object. Each thread that may b running in same processor or different processor has local copy of variable. If one thread in cache L1 modifies the value of variable, another thread will not be able to see the value in L1 cache thread as L2 cache has local value stored in it. The changed value may not reflect in main memory instantly. It depends on write policy of cache. Now the other thread is not aware of the modified data and hence leads to data inconsistency. By declaring variable as volatile it is updated in main memory so that the other thread gets the modified value.

Using of volatile

public class Task{
 
    private static int number;
    private static boolean active;
 
    private static class taskReader extends Thread {
 
        @Override
        public void run() {
            while (!active) {
                Thread.yield();
            }
            System.out.println(number);
        }
    }
 
    public static void main(String[] args) {
        new taskReader().start();
        number = 10;
        active = true;
    }
}

This task class is maintaining 2 simple variables in its main method number and active. taskReader class runs a thread which prints the number when active variable is false.

It’s easy to expect the print of number after short delay. However it may hang for longer or hang forever. Let us understand the cause in more detail below.

Memory Visibility

In this example there are 2 threads main and taskReader thread. Let’s take a scenario in which OS scheduler schedules the threads in two different cores.
1. The main thread has copy of number and active variable stored.
2. The taskReader thread also has the local copy of number and variables.
3. The main thread updates the cache value. The updated values are written in buffer. After a while it gets updated to main memory all at once.
4. When main thread updates the variable value there is no guarantee that the taskReader thread sees this updated value right away.

Reordering

The taskReader thread may read the data in any order than actual program.
It is very likely to expect above program to print 10 but it does not due to reordering.
1. JIT may optimize via reordering
2. The processor may flush the write buffer in any order.


6 Important points on volatile:

  1. The “volatile” modifier in java can only be used with member variables, Class object and class variables, primitive and reference types.
  2. Reading and writing to “volatile” variable causes the reading and writing into main memory which is more expensive than CPU cache.
  3. It is thread safe as data is flushed and read from main memory hence making sure that “thread” sees the right copy of variable. Access to it is automatically “synchronized“.
  4. Volatile” cannot be used with final as it make no sense to make use of both in a variables as final value cannot be changes. You encounter compilation error if you are trying to use volatile with final.
  5. It can be used with static as static variables are store in class level this mean many objects will be sharing this variable.
  6. Do not use this keyword if a variable is not shared between multiple threads. s usage of main memory is costly.