×

Java Volatile Keyword

The compiler, runtime, or processors may use any kind of optimization if there aren't any required synchronizations. Although most of the time these improvements are advantageous, they occasionally can result in minor problems.

Among the optimizations that could surprise us in concurrent situations are caching and reordering. The volatile keyword is one of the various mechanisms offered by Java and the JVM for managing memory order. Program instructions must be carried out by processors. As a result, they must pull the necessary data and program instructions from RAM.

Fetching from RAM isn't the best option for CPUs because of how many instructions per second they can process. Processors are employing techniques like Out of Order Execution, Branch Prediction, Speculative Execution, and, of course, Caching to improve this problem. When a Java variable is "being stored in main memory," the Java volatile keyword is used to indicate this.

Since Java 5, the volatile keyword ensures more than only main memory access for volatile variables. In the sections that follow, I shall explain.

In this article, we'll concentrate on the volatile keyword, a fundamental yet sometimes misunderstood Java language notion. We'll begin by providing some background information on the fundamental principles of computer architecture before becoming acquainted with Java's concept of memory order.

Multiple threads can change a variable's value by using the volatile keyword. Making classes thread safe is another use for it. It means that using a method or an instance of a class by several threads is not problematic. Both primitive types and objects are compatible with the volatile keyword.

The volatile keyword always reads the variable's value from the main memory rather than caching it. Classes and methods cannot be combined with the volatile keyword. It is utilized with variables, though. It also ensures order and visibility. It stops code from being rearranged by the compiler.

The volatile keyword is required to prevent such accesses from being optimized away by the compiler since the contents of the specific device register could change at any time.

Using volatile is yet another method of making a class thread-safe (along with synchronized and atomic wrapper). A method or class instance is said to be thread-safe if it can be utilized by several threads concurrently without encountering any issues.

Example

By consider the example given below. Variable changes between threads are guaranteed to be visible thanks to the Java volatile keyword. Let me explain because this might sound a little abstract.

class S_Obj
{
   // Changes made to s_Var in one thread
   // may cannot reflect immediately in other thread
   static int s_Var = 9;

Let's say that SharedObj is being worked on by two threads. Each thread may have its own local copy of the sharedVariable if they are running on different CPUs. If a value is modified by one thread, the original value stored in main memory could not immediately reflect the change. This is dependent on the cache's write policy. Since the other thread is currently unaware of the modified value, inconsistent data results.

Simple example of volatile

class Testcase
{  
static int v=8;}

Assume that two threads are working on the same class in the example. Each thread has its own local copy of var, and both threads are running on different CPUs. If any thread updates it, the modified value won't be reflected in the main memory's original. Because the other thread is unaware of the updated value, it causes data inconsistency.

class Test  
{  
static volatile int v =8;
}  

Static variables are class members that are shared by all objects in the example above. In the main memory, there is just one copy. A volatile variable's value will never be kept in the cache. The main memory will be used for all read and write operations.

When to Use the Volatile

  • If you wish to automatically read and write long and double variables, you can do so by using a volatile variable.
  • It can be utilized as a different approach to synchronization in Java.
  • After the write operation is finished, the volatile variable's changed value will be visible in all reader threads. If the volatile keyword is not used, multiple reader threads can view different values.
  • It is employed to let the compiler know that several threads will make use of a specific statement. It prohibits the compiler from performing any optimization or reordering.
  • If you don't utilize volatile variables, the compiler can rearrange the code and read from main memory rather than writing the volatile variable value to cache.

A volatile variable's reading or writing does not prevent other threads from doing the same. Use the synchronized keyword around important portions to make this happen.

You may alternatively use one of the various atomic data types present in the java. util. concurrent package as an alternative to a synchronized block. The AtomicLong, AtomicReference, or one of the others, for instance. This is not ensured if the variable is not made volatile.

Important Points of Volatile

  • The keyword volatile is compatible with variables. It is forbidden to use volatile keywords with classes and methods.
  • It ensures that the volatile variable's value will never be read from the local thread cache but instead from the main memory.
  • Reads and Writes are atomic for volatile variables that you have declared.
  • The likelihood of a memory consistency error is decreased.
  • In Java, any write to a volatile variable creates an occur before relationship with subsequent readings of the same variable.
  • Other threads can always see the volatile variables.
  • An object reference's volatile variable could be null.
  • You do not need to use the volatile keyword with a variable if it is not shared by more than one thread.

Volatile vs Synchronized

Although it is not a synchronized keyword's replacement, a volatile keyword may be utilized in some circumstances.

Java's synchronized keyword guarantees mutual exclusion and visibility. If we synchronies the blocks of threads that change the value of the shared variable, then only one thread can enter the block and changes will be reflected in main memory. If any other thread tries to enter the block concurrently, they will all be blocked and put to sleep.

In some situations, visibility may be the only thing we want, not atomicity. In this case, using synchronized is excessive and could lead to scalability issues. Volatile saves the day in this situation. The visibility aspects of synchronized variables apply to volatile variables, but not the atomicity features. All updates to and reads from the main memory will be made in order to avoid caching the volatile variable's values. However, because atomicity is preferred much of the time, the use of volatile is constrained to a very small number of situations.

For instance, a seemingly simple increment statement like x = x + 1 or x++ is actually a compound read-modify-write series of operations that must carry out atomically.

Examples of Volatile Keyword

We have defined a class in the example below that raises the counter value. When the thread starts running, the modified value and the old value are passed to the run () method in the VolatileThread.java file. The array of threads is defined in the main class.

Example 1:

public class Vol_Data   
{  
private vol int count = 0;
public int getCount ()   
{  
return count;
}  
public void increCount ()   
{  
++count; // the value of counter increses by 1   
}  
}  

Example 2:

public class VolThread extends Thread   
{  
private final VolData da;
public VolThread (VolData da)   
{  
this. da = da;
}  
@Override  
public void run ()  
{  
int oldV = da. getCount ();
System.out.println("[Thread " + Thread.currentThread(). getId () + "]: Old v = " + oldV);
da. increCount ();
int newV = da. getCount ();
System.out.println("[Thread " + Thread.currentThread(). getId() + "]: New v = " + newV);  
}  
} 

Example 3:

public class VolatileMain   
{  


private final static int noOfThreads = 2;
public static void main (String [] args) throws InterruptedException  
{  
VolDa volDa = new VolDa ();
Thread [] threads = new Thread[noOfThreads];  // Thread array is created
for (int i = 0; i < noOfThreads; ++i)  
threads[i] = new VolatileThread(volDa);
for (int i = 0; i < noOfThreads; ++i)  
threads[i]. start ();                 //starts all reader threads  
for (int i = 0; i < noOfThreads; ++i)  
threads[i]. join ();                  //wait for all threads  
}  
}  

Output:

[Thread 9]: Old v = 0
[Thread 9]: New v = 1
[Thread 10]: Old v= 1
[Thread 10]: New v = 2

Volatile variables are read and written into main memory when they are read and written, respectively. Accessing the CPU cache is less expensive than reading or writing to main memory. Accessing volatile variables also prevents the common performance improvement method of instruction reordering. Therefore, you should only use volatile variables when it is absolutely necessary to ensure variable visibility.


Related Topics

Java Calculate Average of List

The list is a linear data structure used in Java to store ordered data collections. Additionally, it accepts duplicate values while maintaining insertion order. It is sometimes necessary to find...

3 minutes read.

Constructor Chaining and Constructor Overloading in Java

Constructor Chaining Constructor chaining and constructor overloading are two confusing terms. Let's first understand constructor chaining.Constructor chaining is the process of calling one constructor from another constructor using the same object....

2 minutes read.

Stone Game in Java

In this tutorial, we will learn to design a stone game in Java. First of all, we will understand what is this game all about. We will grasp it through...

9 minutes read.

Java Math decrementExact() Method

The decrementExact() method of Math class returns the argument which is decremented by one, throwing an exception is the result overflows an int or long. Syntax: public static int decrementExact (int a) Parameters: The...

1 minute read.

Java Package Keyword

A collection of classes, interfaces, and subpackages in a Java program are referred to as a package. Here, we'll learn in-depth how to make and use user-defined packages. package is a...

6 minutes read.

How to Create an Object in Java

How to Create an Object in Java An object can be defined as a run time entity that contains the blue printof the class. It means that all the member functions...

5 minutes read.

How to get the current date and time in Java

Introduction: In this article, we are going to discover many processes for Getting the existing-day Date and Time in Java. Most programs require timestamping events or showing date/times, among many...

3 minutes read.

Java Enum vs Class

Enumerations are used in programming languages to represent collections of named constants. For instance, the four suits in a deck of playing cards might represent four integrators named Club, Diamond,...

7 minutes read.

What is anagram in Java?

In this section will explain what an anagram is in Java and demonstrate how to determine whether or not a text is an anagram. In Java interviews, the anagram Java...

4 minutes read.

Java Math.multiplyExact() method

In java, we are provided with multiplyExact method in the Math module. This Math module belongs to the java.lang package. In general, this method returns the product of the provided...

2 minutes read.

Null Pointer Exception in Java

It is a runtime error exception. The null value is allocated to the object reference in this exception. We will explicitly throw this null pointer exception when the program wants...

3 minutes read.

Java Math cosh() Method

The cosh() method of Math class returns the first hyperbolic cosine((e+e)/2) of a double value. Syntax: public static double cosh(double x) Parameters: The parameter ‘x’ represents the number whose hyperbolic cosine is to be...

2 minutes read.

Java Boolean toString() Method

The toString() method of Java Boolean class returns a String corresponding to this Boolean object. It returns a string value “true”, if the defined object is true else it returns...

2 minutes read.

Sublime Number in Java

In this tutorial, we will understand what is meant by sublime number in java. From the point of the coding interview, it is one of the important topics. We will we will...

4 minutes read.

Java Array Generic

Creating Generic Array in Java A collection of comparable sorts of data is kept in an array. In Java, making a generic array is challenging. The type information of an array's...

4 minutes read.

Minimum Number of Taps to Open to Water a Garden in Java

Problem Statement The issue is that a gardener wants to water a (single-dimensional) garden using the fewest possible tap openings. The goal is to determine the minimum necessary taps to be...

8 minutes read.

Heap Sort in Java

Heap Sort in JavaHeap sort in Java uses the data structure binary heap, min-heap, or max heap to do the sorting of elements. Since min-heap always gives the minimum element first,...

8 minutes read.

Java class class

Java Class class instances are an executing Java application's implementation of the classes and interfaces. As well as, every Array is indeed an object that is common for all Arrays...

6 minutes read.

Difference between String and Char Array in Java

We are heading to examine some significant differences between String and Character arrays. Both char arrays and String hold the series of characters and are utilised as a cluster of...

3 minutes read.

Interface Program in Java

Interface Program in Java In the previous topic, we discussed that abstraction is possible through the interface and abstract class. An abstract class provides partial to 100% abstraction. 100 %abstraction in...

4 minutes read.