In general each thread has its own copy of variable, such that one
thread is not concerned with the value of same variable in the other
thread. But sometime this may not be the case. Consider a scenario in
which the count variable is holding the number of times a method is
called for a given class irrespective of any thread calling, in this
case irrespective of thread access the count has to be increased. In
this case the count variable is declared as volatile.
The copy of volatile variable is stored in the main memory, so
every time a thread access the variable even for reading purpose the
local copy is updated each time from the main memory. The volatile
variable also have performance issues.
Volatile keyword in Java is used as an indicator to Java compiler and Thread that do not cache value of this variable and always read it from main memory. So if you want to share any variable in which read and write operation is atomic by implementation e.g. read and write in int or boolean variable you can declare them as volatile variable.
Java introduces some change in Java Memory Model (JMM), Which guarantees visibility of changes made by 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. Java volatile keyword cannot be used with method or class and it can only be used with variable. Java volatile keyword also guarantees visibility and ordering , after Java 5 write to any volatile variable happens before any read into volatile variable. By the way use of volatile keyword also prevents compiler or JVM from reordering of code or moving away them from synchronization barrier.
Volatile keyword in Java is used as an indicator to Java compiler and Thread that do not cache value of this variable and always read it from main memory. So if you want to share any variable in which read and write operation is atomic by implementation e.g. read and write in int or boolean variable you can declare them as volatile variable.
Java introduces some change in Java Memory Model (JMM), Which guarantees visibility of changes made by 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. Java volatile keyword cannot be used with method or class and it can only be used with variable. Java volatile keyword also guarantees visibility and ordering , after Java 5 write to any volatile variable happens before any read into volatile variable. By the way use of volatile keyword also prevents compiler or JVM from reordering of code or moving away them from synchronization barrier.
Example of volatile keyword in Java:
To Understand example of volatile keyword in java let’s go back to Singleton pattern in Java and see double checked locking in Singleton with Volatile and without 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;
}
* 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:
1) We are only creating instance one time
2) We are creating instance lazily at the time of first request comes.
If we do not make _instance variable volatile then Thread which is creating 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 value of _instance as not null and they will believe
its still null.
Why because reader threads are not doing any locking and until writer thread comes out of synchronized block, memory will not be synchronized and value of _instance will not be updated in main memory. With Volatile keyword in Java this is handled by Java himself and such updates will be visible by all reader threads.
When to use Volatile variable in Java
1) You can use Volatile variable if you want to read and write long and double variable atomically. long and double both are 64 bit data type and by default writing of long and double is not atomic and platform dependence. Many platform perform write in long and double variable 2 step, writing 32 bit in each step, due to this its possible for a Thread to see 32 bit from two different write. You can avoid this issue by making long and double variable volatile in Java.
2) Volatile variable can be used as an alternative way of achieving synchronization in Java in some cases, like Visibility. with volatile variable its guaranteed that all reader thread will see updated value of volatile variable once write operation completed, without volatile keyword different reader thread may see different values.
3) volatile variable
can be used to inform compiler that a particular field is subject to be
accessed by multiple threads, which will prevent compiler from doing
any reordering or any kind of optimization which is not desirable in
multi-threaded environment. Without volatile variable compiler can re-order code, free to cache value of volatile variable instead of always reading from main memory. like following example without volatile variable may result in infinite loop
private boolean isActive = thread;
public void printMessage(){
while(isActive){
System.out.println("Thread is Active");
}
}
public void printMessage(){
while(isActive){
System.out.println("Thread is Active");
}
}
without volatile modifier its not guaranteed that one Thread see the updated value of isActive
from other thread. compiler is also free to cache value of isActive
instead of reading it from main memory in every iteration. By making isActive a volatile variable you avoid these issue.
4) Another place where volatile variable can be used is to fixing double checked locking in Singleton pattern.
Important points on Volatile keyword in Java
1. volatile keyword in Java is only application to variable and using volatile keyword with class and method is illegal.
2. volatile keyword in Java guarantees that value of volatile variable will always be read from 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 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 use
of volatile keyword in Java.
7. An access to a volatile variable in Java never has 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 means atomic, its 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 no need to use volatile keyword with that variable.
Difference between synchronized and volatile keyword in Java
Difference between volatile and synchronized is another popular core Java question asked in multi-threading and concurrency interviews. Remember volatile
is not a replacement of synchronized keyword but can be used as an
alternative in certain cases. Here are few differences between volatile and synchronized keyword in Java.
1. Volatile keyword in java is a field modifier, while synchronized modifies code blocks and methods.
2. Synchronized obtains and releases lock on monitor’s java volatile keyword doesn't require that.
3. Threads in Java can be blocked for waiting any monitor in case of synchronized, that is not the case with volatile keyword in Java.
4. Synchronized method affects performance more than 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 variable 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 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
No comments:
Post a Comment