How Volatile in Java works? Example of volatile keyword in Java (original) (raw)
What is a volatile variable in Java and when to use the volatile variable in Java is a famous multi-threading interview question in Java interviews? Though many programmers know what is a volatile variable they fail on the second part i.e. were to use volatile variables in Java as it's not common to have a clear understanding and hands-on on volatile variables in Java. In this tutorial, we will address this gap by providing a simple example of the volatile variable in Java and discussing when to use the volatile variable in Java. Anyway, the volatile keyword in Java is used as an indicator to Java compiler and Thread that do not cache the value of this variable and always read it from the main memory.
So if you want to share any variable in which read and write operation is atomic by implementation like reading and write in an int or a boolean variable then you can declare them as a volatile variable.
From Java 5 along with major changes like Autoboxing, Enum, Generics, and Variable arguments, Java introduces some change in the Java Memory Model (JMM), Which guarantees visibility of changes made from one thread to another also as "happens-before" which solves the problem of memory writes that happen in one thread can "leak through" and be seen by another thread.
The Java volatile keyword cannot be used with method or class and it can only be used with a variable. Java volatile keyword also guarantees visibility and ordering, after Java 5 writes to any volatile variable happens before any read into the volatile variable.
By the way use of volatile keywords also prevents the compiler or JVM from the reordering of code or moving away from them from the synchronization barrier.
What is volatile variable in Java? An Example
To Understand the example of volatile keyword in Java let’s go back to the Singleton pattern in Java and see double-checked locking in Singleton with Volatile and without the volatile keyword in java.
/**
- Java program to demonstrate where to use Volatile keyword in Java.
- In this example Singleton Instance is declared as volatile variable to ensure
- every thread see updated value for _instance.
- @author Javin Paul */ public class Singleton{ private static volatile Singleton _instance; //volatile variable
public static Singleton getInstance(){
if(_instance == null){ synchronized(Singleton.class){ if(_instance == null) _instance = new Singleton(); }
} return _instance;
}
If you look at the code carefully you will be able to figure out:
- We are only creating instances one time
- We are creating instances lazily at the time the first request comes.
If we do not make the _instance variable volatile then the Thread which is creating an instance of Singleton is not able to communicate other thread, that instance has been created until it comes out of the Singleton block, so if Thread A is creating Singleton instance and just after creation lost the CPU, all other thread will not be able to see the value of _instance as not null and they will believe it's still null.
Why? because reader threads are not doing any locking and until the writer thread comes out of the synchronized block, the memory will not be synchronized and the value of _instance will not be updated in the main memory.
With Volatile keyword in Java, this is handled by Java himself and such updates will be visible by all reader threads. So in Summary apart from synchronized keywords in Java, a volatile keyword is also used to communicate the content of memory between threads.
Let’s see another example of a volatile keyword in Java
most of the time while writing game we use a variable bExit to check whether the user has pressed the exit button or not, the value of this variable is updated in the event thread and checked in the game thread, So if we don't use volatile keyword with this variable, Game Thread might miss an update from event handler thread if it's not synchronized in Java already.
The volatile keyword in java guarantees that the value of the volatile variable will always be read from the main memory and the "happens-before" relationship in the Java Memory model will ensure that the content of memory will be communicated to different threads.
private boolean bExit;
while(!bExit) { checkUserPosition(); updateUserPosition(); }
In this code example, One Thread (Game Thread) can cache the value of "bExit" instead of getting it from the main memory every time and if in between any other thread (Event handler Thread) changes the value; it would not be visible to this thread. Making boolean variable "bExit" as volatile in java ensures this will not happen.
Also, If you have not read it already then I also suggest you read the topic about volatile variables from Java Concurrency in Practice book by Brian Goetz, one of the must-reads to truly understand this complex concept.
When to use Volatile variable in Java? Example
One of the most important things in the learning of volatile keywords is understanding when to use a volatile variable in Java. Many programmers know what is volatile variable and how does it work but they never really used a volatile modifier for any practical purpose. Here are a couple of examples to demonstrate when to use the volatile keyword in Java:
1. You can use the Volatile variable if you want to read and write long and double variables atomically. long and double both are 64-bit data types and by default writing of long and double is not atomic and platform dependence.
Many platforms perform write in long and double variable 2 step, writing 32 bit in each step, due to this it's possible for a Thread to see 32 bit from two different writers. You can avoid this issue by making the long and double variable volatile in Java.
2. A volatile variable can be used as an alternative way of achieving synchronization in Java in some cases, like Visibility. with volatile variable, it's guaranteed that all reader threads will see the updated value of the volatile variable once the write operation is completed, without volatile keyword different reader thread may see different values.
3. volatile variable can be used to inform the compiler that a particular field is subject to be accessed by multiple threads, which will prevent the compiler from doing any reordering or any kind of optimization which is not desirable in a multi-threaded environment.
Without a volatile variable, the compiler can re-order the code, free to cache value of volatile variable instead of always reading from main memory. like the following example without volatile variable may result in an infinite loop
private boolean isActive = thread; public void printMessage(){ while(isActive){ System.out.println("Thread is Active"); } }
without the volatile modifier, it's not guaranteed that one Thread sees the updated value of isActive from other threads. The compiler is also free to cache the value of isActive instead of reading it from the main memory in every iteration. By making isActive a volatile variable you avoid these issues.
4. Another place where a volatile variable can be used is to fix double-checked locking in the Singleton pattern. As we discussed in Why should you use Enum as Singleton that double-checked locking was broken in Java 1.4 environment?
Important points on Volatile keyword in Java
1. The volatile keyword in Java is the only application to a variable and using a volatile keyword with class and method is illegal.
2. volatile keyword in Java guarantees that the value of the volatile variable will always be read from the main memory and not from Thread's local cache.
3. In Java reads and writes are atomic for all variables declared using Java volatile keyword (including long and double variables).
4. Using the volatile keyword in Java on variables reduces the risk of memory consistency errors because any write to a volatile variable in Java establishes a happens-before relationship with subsequent reads of that same variable.
5. From Java 5 changes to a volatile variable are always visible to other threads. What's more, it also means that when a thread reads a volatile variable in Java, it sees not just the latest change to the volatile variable but also the side effects of the code that led up the change.
6. Reads and writes are atomic for reference variables are for most primitive variables (all types except long and double) even without the use of volatile keyword in Java.
7. Access to a volatile variable in Java never has a chance to block, since we are only doing a simple read or write, so unlike a synchronized block we will never hold on to any lock or wait for any lock.
8. Java volatile variable that is an object reference may be null.
9. Java volatile keyword doesn't mean atomic, it's a common misconception that after declaring volatile ++ will be atomic, to make the operation atomic you still need to ensure exclusive access using synchronized method or block in Java.
10. If a variable is not shared between multiple threads, you don't need to use a volatile keyword with that variable.
Difference between synchronized and volatile keywords in Java
What is the difference between volatile and synchronized is another popular core Java question asked on multi-threading and concurrency interviews. Remember volatile is not a replacement of a synchronized keyword but can be used as an alternative in certain cases.
Here are a few differences between volatile and synchronized keywords in Java.
1. The volatile keyword in Java is a field modifier while synchronized modifies code blocks and methods.
2. Synchronized obtains and releases the lock on the monitor’s Java volatile keyword doesn't require that.
3. Threads in Java can be blocked for waiting for any monitor in case of synchronization, that is not the case with the volatile keyword in Java.
4. Synchronized method affects performance more than a volatile keyword in Java.
5. Since volatile keyword in Java only synchronizes the value of one variable between thread memory and "main" memory while synchronized synchronizes the value of all variables between thread memory and "main" memory and locks and releases a monitor to boot. Due to this reason, synchronized keyword in Java is likely to have more overhead than volatile.
6. You can not synchronize on the null object but your volatile variable in Java could be null.
7. From Java 5 writing into a volatile field has the same memory effect as a monitor release, and reading from a volatile field has the same memory effect as a monitor acquire
In short, the volatile keyword in Java is not a replacement of a synchronized block or method but in some situations is very handy and can save performance overhead which comes with the use of synchronization in Java. If you like to know more about volatile I would also suggest going thorough FAQ on Java Memory Model here which explains the happens-before operations quite well.
Other Java concurrency tutorials from Javarevisited you may like
- Difference between Runnable and Thread in Java
- How to use CyclicBarrier in Java with Example
- What is ConcurrentHashMap in Java
- How to use CountDownLatch in Java with Example
- How to solve the producer-consumer problem with BlockingQueue in Java
- What is a thread-safe class, How to write thread-safe code in Java?
- What is happens-before in Java concurrency?
- How to use Future and FutureTask class in Java?
- Difference between volatile, atomic, and synchronized in Java?
- How to use the Lock interface in multi-threaded programming?
- how to do inter-thread communication using wait and notify?
- ForkJoin vs Executor Framework in Java?
- How to use ThreadLocal variables in Java? (example)
- Top 5 Concurrent Collection classes from Java 5 and Java 6?
Thanks for reading this article so far. If you like this Java volatile tutorial and example then please share it with your friends and colleagues. If you have any questions or feedback then please drop a note.
P.S. - If you are new to the Java Programming field and need a free course to learn essential Java multithreading tools, libraries, and concepts then I highly suggest you join this** free Java Multithreading course for beginners**. This is a free Udemy course to learn Java Multithreading from scratch.
> Now, over to you; What is difference between atomic, volatile, and synchronized variable in Java? Can you replace volatile with atomic variables?