Java allows threads to access shared variables. As a rule, to ensure that shared variables are consistently updated, a thread should ensure that it has exclusive use of such variables by obtaining a lock that enforces mutual exclusion for those shared variables.
A mutual exclusion (mutex) is a program object that prevents simultaneous access to a shared resource.
If a field is declared volatile, in that case the Java memory model ensures that all threads see a consistent value for the variable.
What could be impact of not using volatile keyword?
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 the first request comes.
If we do not make the _instance variable volatile than the 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.
- Java allows threads to access shared variables. As a rule, to ensure that shared variables are consistently updated, a thread should ensure that it has exclusive use of such variables by obtaining a lock that enforces mutual exclusion for those shared variables. We can ensure such behaviour by using volatile keyword.
- If a field is declared volatile, in that case the Java memory model ensures that all threads see a consistent value for the variable.
- Volatile can be used as a keyword against the variable, we cannot use volatile against method declaration.
volatile void method2() //it’s illegal
volatile int i; //legal
- In certain cases, Volatile keyword can be used as an alternate to synchronization in java, as all threads always have access to latest updated value.
- Using volatile is better than synchronization, as synchronization needs to block whole method (if used in method declaration) or block (if synchronization block is used), while volatile needs not to block any piece of code.
- Not Cached in CPU- Volatile members are never cached in CPU by jvm, they are always read from main memory i.e. from stack where variable lives.
It is possible for multiple CPU’s to exist on machine, so it is possibility that thread might cache different values in different CPU’s for same variable, so it’s important that value is not cached in CPU and always read from main memory.
- Volatile keyword must be used in multithreading environment, there is no use of using volatile keyword in non multi threading environment, it may cost us unnecessary performance issue as volatile keyword is not cached in memory by jvm.
- A compile-time error will occur if a final variable is declared volatile.
volatile final int x = 0; //The field x can be either final or volatile, not both.
|
- If variable which has been declared volatile, is a reference to object it may point to null as well,
volatile Integer i=null; //it’s allowed.
|
- Performance issue - As volatile keyword is not cached in CPU, it is always read from main memory, so in terms of performance it’s always expensive to use volatile keyword.
No comments:
Post a Comment