What Is Volatile Keyword In Java

By | | Updated : 2021-03-12 | Viewed : 2214 times

What Is Volatile Keyword In Java

In multi-threading applications, data consistency is one of the significant challenges to make the application stable. The volatile keyword is one of the options to maintain data consistency. The Volatile keyword is a qualifier that is applied to a variable when it is declared.

What is the Memory Visibility Problem in Java?

Please consider below given an example in multi-threading.

ShareableCounter.java
public class ShareableCounter {
	public int counter = 0;
}

Two threads, as shown below, are using the same SharableObject.

Example Threads
ThreadWriter writer= new Thread ( shareableCounter);
ThreadReader reader = new Thread ( shareableCounter);

Here both threads are trying to access the shareableCounter. ThreadWriter has modified the state of SharableObject and will keep the modification in Thread Cache. ThreadWriter is not aware of these modifications as these are not in the main memory. In thread execution, The Thread will not capture the internal object's state changes from Cache into Main memory. In multi-threading, as shown above, Each Thread may contain different values in respective caches. When Thread execution complete, the thread saves the result in the main memory.

Due to this data inconsistency problem might be raised. The data inconsistency problem was called a Variable visibility problem in Java multi-threading.

Please see the diagram for a better understanding.

What Is Volatile Keyword In Java

Volatile keyword in Java?

To overcome the above problem, Volatile is one of the options. Volatile will make threads to save the intermediate modifications into the main memory. So other threads can aware of these modifications.

When the thread modifies the Volatile variable, the master copy has been updated with the local copy. So other Thread can have a chance to read the master before changing its local composition. Each internal modification of each thread can be updated to the master. Hence other threads can read changes from the master copy before updating the local copy.

Example of Volatile keyword in Java

VolatileClientApp.java
package com.docsconsole.voltile;

import java.util.logging.Level;
import java.util.logging.Logger;

public class VolatileClientApp {

    private static final Logger LOGGER = Logger.getLogger("Volatile");
    private static volatile int COUNTER = 0;

    public static void main(String[] args) {

        IncrementListner il = new IncrementListner();
        Incrementer  i = new Incrementer();
        Thread t1 =new Thread(il);
        t1.start();
        Thread t2 = new Thread(i);
        t2.start();
    }

    static class IncrementListner implements Runnable {
        @Override
        public void run() {
            int localCounter = COUNTER;
            while ( localCounter < 5){
                if( localCounter!= COUNTER){
                    LOGGER.log(Level.INFO,"Got Change for COUNTER : {0}", COUNTER);
                    localCounter= COUNTER;
                }
            }
        }
    }

    static class Incrementer implements Runnable{
        @Override
        public void run() {

            int localCounter = COUNTER;
            while (COUNTER <5){
                LOGGER.log(Level.INFO, "Incrementing COUNTER to {0}", localCounter+1);
                COUNTER = ++localCounter;
                try {
                    Thread.sleep(500);
                } catch (InterruptedException e) { e.printStackTrace(); }
            }
        }
    }
}

Difference between Volatile and Synchronized?

Usually, each thread will be created in the different CPU cores. Once the thread complete with its execution, it is required to write all the result data from CPU Cache to the main memory where data consistency will have occurred.

Firstly, we will be discussing the thread-safety aspects which will be used for making for threads safety. Two factors are there for making the thread-safety.

Memory Visibility

This aspect will take care of memory visibility to Main Memory when modifications have done in Thread Cache. Generally speaking, In multi-threading, the intermediate changes performed by a Thread execution will be stored in the Thread cache, which is the CPU cache. There is no chance of aware of all these intermediate modifications of one thread to the other threads. Thus, data changes will not be visible to the main memory. Due to this Memory non visibility, data will be inconsistent.

Execution Control

This aspect will take care of controlling access in multi-threading. When multiple threads are trying to access the sharable object, then there is a chance of data inconsistency. With a synchronized keyword and block, it will be getting the lock of the monitoring object. When the thread's execution complete, all the result data were updated in the CPU's main memory.

When to use Volatile in Java?

When we have read-update-write of a variable in multi-threading, volatility can be one of the options. It is better to understand very well about the use case.

Even though Volatile guarantees to handle Memory visibility, there are some problems with the volatile keyword. The most useful case is when one thread is for writing, and one or more is for reading.

If Threads count is more for reading and writing the sharable data, it is not a fair use case for the Volatile keyword.

Performance issues in Volatile usage?

For example, we have a shareable object with multiple threads. The shareable class has given below.

SharableObject.java
public calss SharableObject {
	private long phone;
	private volatile int income;
}

Here, all the write operations should be happening before the reading. The order is significant.

Suppose one Thread-write-1 is modifying all the variables. But the modification order is income after that phone. But other threads can access the same object and can try to change before Thread-write-1 modification. So data will not be in sync with write operations with the reading operation. Writing changes from thread cache to the Main memory is one of the expensive procedures. In the case of multi-threading, the chance of increasing the number of reads and writes between thread cache and main memory.

So volatile will be tweaking the performance in program execution. So it would be best if you think twice before using the volatile keyword in Java.

Leave A Reply