Do you ever use the volatile keyword in Java?

At work today, I came across the volatile keyword in Java. Not being very familiar with it, I found this explanation:

Java theory and practice: Managing volatility

Given the detail in which that article explains the keyword in question, do you ever use it or could you ever see a case in which you could use this keyword in the correct manner?


volatile has semantics for memory visibility. Basically, the value of a volatile field becomes visible to all readers (other threads in particular) after a write operation completes on it. Without volatile , readers could see some non-updated value.

To answer your question: Yes, I use a volatile variable to control whether some code continues a loop. The loop tests the volatile value and continues if it is true . The condition can be set to false by calling a "stop" method. The loop sees false and terminates when it tests the value after the stop method completes execution.

The book "Java Concurrency in Practice," which I highly recommend, gives a good explanation of volatile . This book is written by the same person who wrote the IBM article that is referenced in the question (in fact, he cites his book at the bottom of that article). My use of volatile is what his article calls the "pattern 1 status flag."

If you want to learn more about how volatile works under the hood, read up on the Java memory model. If you want to go beyond that level, check out a good computer architecture book like Hennessy & Patterson and read about cache coherence and cache consistency.


“… the volatile modifier guarantees that any thread that reads a field will see the most recently written value.” - Josh Bloch

If you are thinking about using volatile , read up on the package java.util.concurrent which deals with atomic behaviour.

The Wikipedia post on a Singleton Pattern shows volatile in use.


Important point about volatile:

  • Synchronization in Java is possible by using Java keywords synchronized and volatile .
  • In Java, we can not have synchronized variable. Using synchronized keyword with a variable is illegal and will result in compilation error. Instead of using the synchronized variable in Java, you can use the java volatile variable, which will instruct JVM threads to read the value of volatile variable from main memory and don't cache it locally.
  • If a variable is not shared between multiple threads then there is no need to use volatile keyword.
  • source

    Example usage of volatile:

    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;
        }
    }
    

    We are creating instance lazily at the time the first request comes.

    If we do not make the _instance variable volatile then the Thread which is creating the instance of Singleton is not able to communicate to the other thread. So if Thread A is creating Singleton instance and just after creation, the CPU corrupts etc, all other threads will not be able to see the value of _instance as not null and they will believe it is still assigned null.

    Why does this happen? Because reader threads are not doing any locking and until the writer thread comes out of a synchronized block, the memory will not be synchronized and value of _instance will not be updated in main memory. With the Volatile keyword in Java, this is handled by Java itself and such updates will be visible by all reader threads.

    Conclusion : volatile keyword is also used to communicate the content of memory between threads.

    Example usage of without volatile:

    public class Singleton{    
        private static Singleton _instance;   //without volatile variable
        public static Singleton getInstance(){   
              if(_instance == null){  
                  synchronized(Singleton.class){  
                   if(_instance == null) _instance = new Singleton(); 
          } 
         }   
        return _instance;  
        }
    

    The code above is not thread-safe. Although it checks the value of instance once again within the synchronized block (for performance reasons), the JIT compiler can rearrange the bytecode in a way that the reference to the instance is set before the constructor has finished its execution. This means the method getInstance() returns an object that may not have been initialized completely. To make the code thread-safe, the keyword volatile can be used since Java 5 for the instance variable. Variables that are marked as volatile get only visible to other threads once the constructor of the object has finished its execution completely.
    Source

    在这里输入图像描述

    volatile usage in java The fail-fast iterators are typically implemented using a volatile counter on the list object.

  • When the list is updated, the counter is incremented.
  • When an Iterator is created, the current value of the counter is embedded in the Iterator object.
  • When an Iterator operation is performed, the method compares the two counter values and throws a ConcurrentModificationException if they are different.
  • The implementation of fail-safe iterators is typically light-weight. They typically rely on properties of the specific list implementation's data structures. There is no general pattern.

    链接地址: http://www.djcxy.com/p/17416.html

    上一篇: Javascript匿名函数调用

    下一篇: 你有没有在Java中使用volatile关键字?