Using volatile is yet another way (like synchronized, atomic wrapper) of making class thread-safe. Thread-safe means that a method or class instance can be used by multiple threads at the same time without any problem. Consider the below example.
class SharedObj
{
// Changes made to sharedVar in one thread
// may not immediately reflect in other thread
static int sharedVar = 6;
}
Suppose that two threads are working on SharedObj. If two threads run on different processors each thread may have its own local copy of sharedVariable. If one thread modifies its value the change might not reflect in the original one in the main memory instantly. This depends on the write policy of cache. Now the other thread is not aware of the modified value which leads to data inconsistency. The below diagram shows that if two threads are run on different processors, then the value of sharedVariable may be different in different threads.
Note that writing of normal variables without any synchronization actions, might not be visible to any reading thread (this behavior is called sequential consistency). Although most modern hardware provides good cache coherence, therefore, most probably the changes in one cache are reflected in another but it’s not a good practice to rely on hardware to ‘fix’ a faulty application.
class SharedObj
{
// volatile keyword here makes sure that
// the changes made in one thread are
// immediately reflect in other thread
static volatile int sharedVar = 6;
}
Note that volatile should not be confused with the static modifier. static variables are class members that are shared among all objects. There is only one copy of them in the main memory.
volatile vs synchronized: Before we move on let’s take a look at two important features of locks and synchronization.
- Mutual Exclusion: It means that only one thread or process can execute a block of code (critical section) at a time.
- Visibility: It means that changes made by one thread to shared data are visible to other threads.
Java’s synchronized keyword guarantees both mutual exclusion and visibility. If we make the blocks of threads that modify the value of the shared variable synchronized only one thread can enter the block and changes made by it will be reflected in the main memory. All other threads trying to enter the block at the same time will be blocked and put to sleep.
In some cases, we may only desire visibility and not atomicity. The use of synchronized in such a situation is overkill and may cause scalability problems. Here volatile comes to the rescue. Volatile variables have the visibility features of synchronized but not the atomicity features. The values of the volatile variable will never be cached and all writes and reads will be done to and from the main memory. However, the use of volatile is limited to a very restricted set of cases as most of the times atomicity is desired. For example, a simple increment statement such as x = x + 1; or x++ seems to be a single operation but is really a compound read-modify-write sequence of operations that must execute atomically.
Java
// Java Program to demonstrate the
// use of Volatile Keyword in Java
public class VolatileTest {
private static final Logger LOGGER
= MyLoggerFactory.getSimplestLogger();
private static volatile int MY_INT = 0;
public static void main(String[] args)
{
new ChangeListener().start();
new ChangeMaker().start();
}
static class ChangeListener extends Thread {
@Override public void run()
{
int local_value = MY_INT;
while (local_value < 5) {
if (local_value != MY_INT) {
LOGGER.log(
Level.INFO,
"Got Change for MY_INT : {0}",
MY_INT);
local_value = MY_INT;
}
}
}
}
static class ChangeMaker extends Thread {
@Override public void run()
{
int local_value = MY_INT;
while (MY_INT < 5) {
LOGGER.log(Level.INFO,
"Incrementing MY_INT to {0}",
local_value + 1);
MY_INT = ++local_value;
try {
Thread.sleep(500);
}
catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}
Output (With the Volatile Keyword):
Incrementing MY_INT to 1
Got Change for MY_INT : 1
Incrementing MY_INT to 2
Got Change for MY_INT : 2
Incrementing MY_INT to 3
Got Change for MY_INT : 3
Incrementing MY_INT to 4
Got Change for MY_INT : 4
Incrementing MY_INT to 5
Got Change for MY_INT : 5
Output (Without the Volatile Keyword)
Incrementing MY_INT to 1
Incrementing MY_INT to 2
Incrementing MY_INT to 3
Incrementing MY_INT to 4
Incrementing MY_INT to 5
volatile in Java vs C/C++:
Volatile in Java is different from the “volatile” qualifier in C/C++. For Java, "volatile" tells the compiler that the value of a variable must never be cached as its value may change outside of the scope of the program itself. In C/C++, "volatile" is needed when developing embedded systems or device drivers, where you need to read or write a memory-mapped hardware device. The contents of a particular device register could change at any time, so you need the "volatile" keyword to ensure that such accesses aren't optimized away by the compiler.
Similar Reads
var keyword in Java
The var reserved type name (not a Java keyword) was introduced in Java 10. Type inference is used in var keyword in which it detects automatically the datatype of a variable based on the surrounding context. The below examples explain where var is used and also where you can't use it. 1. We can decl
4 min read
transient keyword in Java
transient is a variables modifier used in serialization. At the time of serialization, if we don't want to save value of a particular variable in a file, then we use transient keyword. When JVM comes across transient keyword, it ignores original value of the variable and save default value of that v
3 min read
Super Keyword in Java
The super keyword in Java is a reference variable that is used to refer to the parent class when we are working with objects. You need to know the basics of Inheritance and Polymorphism to understand the Java super keyword. The Keyword "super" came into the picture with the concept of Inheritance. I
7 min read
Scoped Values in Java
In Java, Scoped variables enable the exchange of immutable data across and between threads. This new API is implemented as an incubator preview feature in Java 20 as part of JEP 439. They are preferred over thread-local variables, especially when a large number of virtual threads are used. This is a
4 min read
final Keyword in Java
The final Keyword in Java is used as a non-access modifier applicable to a variable, a method, or a class. It is used to restrict a user in Java. We cannot use the final keyword in a block. It restricts the user from accessing that particular part of the program, such as restricting the modification
11 min read
Java Keywords
In Java, keywords are the reserved words that have some predefined meanings and are used by the Java compiler for some internal process or represent some predefined actions. These words cannot be used as identifiers such as variable names, method names, class names, or object names. Now, let us go t
5 min read
Important Keywords in Java
Keywords refer to the reserved set of words of a language. These are used for some predefined actions. abstract: It is a non-access modifier applicable for classes and methods. It is used to achieve abstraction. For more, refer to abstract keyword in javaenum: It is used to define enum in Javainstan
2 min read
Java Atomic vs Volatile vs Synchronized
In Java, multithreading can lead to challenges related to thread safety and data consistency. Java provides concurrency mechanisms like Atomic, Volatile, and Synchronized to address these issues and ensure thread safety. These mechanisms offer unique advantages and limitations.Atomic vs Volatile vs
5 min read
Scope of Variables in Java
The scope of variables is the part of the program where the variable is accessible. Like C/C++, in Java, all identifiers are lexically (or statically) scoped, i.e., scope of a variable can be determined at compile time and independent of the function call stack. In this article, we will learn about
7 min read
Difference between volatile and transient keywords in Java
Just like any other programming language, Java has a set of keywords which are reserved and have a special meaning. In this article, we will see the difference between the keywords volatile and transient. Before getting into the differences, let us first understand what each of them actually means.
3 min read