×

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 Clone Array

We frequently need to copy an array to back up its original components. We have a few unique numbers and strings, including Armstrong numbers, palindrome numbers, and palindrome strings. To...

4 minutes read.

Balanced Parentheses in Java

One of the frequent programming issues, commonly referred to as the Balanced brackets issue, is the problem with the balanced parenthesis. Interviewers frequently provide this task, in which we must...

5 minutes read.

Convert Char array to string in java

A collection of characters is referred to as a string. A character array differs from a string in that the string is canceled by the special character "\0." A string...

4 minutes read.

Get year from date in Java

The getYear() method of the Java date class returns a number calculated by deducting 1900 from the year that contains or starts with the instant in time represented by this...

4 minutes read.

Memory Leak in Java

Java offers memory management right out of the box. When we use the new keyword to create an object, the JVM initialises for that object immediately. The trash collector automatically...

3 minutes read.

Java Location

PATH is an environmental variable that the system software now uses to find executable files (.exe) or Java binaries ( java or javac command). Once chosen, a route cannot be...

3 minutes read.

Undo and Redo Operations in Java

Undo and redo operation are the most widely used operation while dealing with file. In this section, we will discuss how to implement undo and redo operation in Java. Undo Redo...

2 minutes read.

StringBuilder in Java

StringBuilder in Java Java StringBuilder class is introduced since JDK 1.5. The StringBuilder class is mainly used to create modifiable or mutable strings. Note that the StringBuilder class is not synchronized....

7 minutes read.

Java Math min() Method

The min() method of Math class returns the smaller of two arguments. The arguments can be of double, float, int or long data type. Syntax: public static double min (double a, double...

2 minutes read.

How to Convert long to String in Java

How to Convert long to String in java It is used if we have to display a long number in the text field because everything is displayed as a String. A...

3 minutes read.

Java 8 Multimap

Java comes with several practical built-in collection libraries. However, there are situations when we need specialized collections that are not included in the Java standard library. The Multimap is one...

7 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.

Java Math subtractExact() Method

The subtractExact() method of Java Math class returns mathematical difference of the specified two arguments, throwing an exception if the result overflows int or long. Syntax: public static int subtractExact (int x,...

1 minute read.

Stock Span Problem Using Stack in Java

The stock span problem is an issue in finance where we must determine a stock’s price span over all N days given a set of N daily price quotes. The...

6 minutes read.

How to calculate time complexity of any program in Java

Java : Java's syntax and principles are derived from the C and C++ languages. We know that java is one of the programming language. The main feature of java which is...

3 minutes read.

Java Boolean logicalXor() Method

The logicalXor() method of Java Boolean class returns the result of implementing logical XOR operation on the specified Boolean operands. Syntax: public static boolean logicalXor (boolean a, boolean b) Parameters: The parameters ‘a’ and...

2 minutes read.

Java Interface Lock

A synchronisation method called the Lock interface is available as of JDK 1.5. It is comparable to a synchronised block but more complex and versatile. The package java.util.concurrent contains the...

4 minutes read.

Java Implements Keyword

To understand about the keyword implements we need to learn about the concept of the interfaces and inheritance in java programming languages. So let us learn about the interface and...

3 minutes read.

Features of Java

The objective of the Java programming language is to provide portability, security, and simplicity. In spite of this, Java has a number of features that makes it a popular language...

5 minutes read.

RMI program in Java

Remote Method Invocation is what it stands for. An object can call the method of another object in a different space address using the RMI API, which may be on the...

3 minutes read.