What is a volatile variable in Java and when should you use it?
Java Multi-threading Interview Questions and Answers
Three of the Java keywords that are very popular in job interviews are 1) volatile 2) transient 3) const
1) volatile is popular because it can be a bit tricky to understand and know when to use it.
2) transient is popular as it is not widely used, but handy in object serialization.
3) const is popular because it is a reserved keyword, but is not currently used. The final keyword on a reference variable just means that the reference cannot be changed to reference a different object. But, the object itself can be changed if their fields are not final. The const is reserved to make the whole object not changeable, but currently not used.
Let's focus now on the "volatile" keyword.
Q. What is a volatile key word in Java?
A. The volatile keyword is used with object and primitive variable references to indicate that a variable's value will be modified by different threads. This means
- The value of this variable will never be cached locally within the thread, and all the reads and writes must go to the main memory to be visible to the other threads. In other words the keyword volatile guarantees visibility.
- From JDK 5 onwards, writing to a volatile variable happens before reading from a volatile variable. In other words, the volatile keyword guarantees ordering, and prevents compiler or JVM from reordering of the code.
Q. How does volatile keyword differ from the synchronized keyword?
A.
- The volatile keyword is applied to variables of both primitives and objects, whereas the synchronized keyword is applied to only objects.
- The volatile keyword only guarantees visibility and ordering, but not atomicity, whereas the synchronized keyword can guarantee both visibility and atomicity if done properly. So, the volatile variable has a limited use, and cannot be used in compound operations like incrementing a variable, etc.
volatile int counter = 0; public void increment(){ counter++; }
Right use of volatile. Example1:
volatile boolean status = false; //... public void process(){ while(!status){ //.... } }
Or in lazy singleton. Example2: Double checked locking
public final Class MySingleton { private static volatile MySingleton instance = null; private MySingleton( ){} public static MySingleton getInstance() { if(instance == null) { synchronized (MySingleton.class) { if(instance == null) { instance = new MySingleton(); } } } return instance; } }
Important: Synchronized keyword (i.e. locking) can guarantee both visibility and atomicity, whereas volatile variables can only guarantee visibility. A synchronized block can be used in place of volatile but the inverse is not true.
So, if you are not sure where to use, then favor the "synchronized" keyword.
Q. Why is locking of a method or block of code for thread safety is called "synchronized" and not "lock" or "locked"?
A. When a method or block of code is locked with the reserved "synchronized" key word in Java, the memory (i.e. heap) where the shared data is kept is synchronized. This means,
- When a synchronized block or method is entered after the lock has been acquired by a thread, it first reads any changes to the locked object from the main heap memory to ensure that the thread that has the lock has the current info before start executing.
- After the synchronized block has completed and the thread is ready to relinquish the lock, all the changes that were made to the object that was locked is written or flushed back to the main heap memory so that the other threads that acquire the lock next has the current info.
This is why it is called "synchronized" and not "locked". This is also the reason why the immutable objects are inherently thread-safe and does not require any synchronization. Once created, the immutable objects cannot be modified.
Labels: Multi-threading
0 Comments:
Post a Comment
Subscribe to Post Comments [Atom]
<< Home