1

I am reading Esteban Herrera's Java 8 Programmer II Study Guide. I already understand the keyword "synchronized," but not "volatile." In the first chapter, the author makes the case for the "volatile" keyword. First, he points out an issue with the following code.

class Singleton {
    private static Singleton instance;
    private Singleton() { }
    public static Singleton getInstance() {
        if(instance == null) {
            synchronized (Singleton.class) {
                if(instance == null) {
                    instance = new Singleton();
                }
            }
        }
        return instance;
    }
}

He calls the above code imperfect, arguing, "The JVM, or sometimes the compiler, can optimize the code by reordering or caching the value of variables (and not making the updates visible)." He recommends adding the volatile keyword to the Singleton instance field because this ensures that its read and write operations will be atomic rather than cached in the case of multiple threads.

I do not fully understand Herrera's argument. What does it mean to reorder the value of variables, and why would this be a problem? What does it mean for read/write operations in multiple threads to be atomic, and why is this necessary? Every explanation that I have found online is likewise full of jargon. Can anyone explain the volatile keyword in layman's terms without assuming a prior understanding of the above terms?

K Man
  • 602
  • 2
  • 9
  • 21
  • 2
    The reordering is called memory ordering - if the compiler can re-order instructions to optimize without affecting the end result, it will. The downside is, it's on a per-thread basis, so although ordering may optimize a single threaded program, it introduces issues in multi-threaded environments. – Vince Aug 31 '19 at 17:35
  • @Seelenvirtuose The answers to that question assume a prior understanding of volatility and atomicity that I do not have, hence my question. Could you please remove the hold? – K Man Aug 31 '19 at 17:46
  • 1
    Atomicy is just a "happens-before" relationship. One action must happen before another, such as a variable being initialized before it's used. Caching is a CPUs ability to cache data, improving performance. You must explicitly prevent that to ensure that data is seen by all threads. Dig into the terms you don't understand, and don't settle on 1 source of information. – Vince Aug 31 '19 at 17:51
  • @KMan the problem with saying "please explain it again in terms I understand" is that we don't know what terms you will understand. You need to identify what specifically about the duplicate answers are unclear to you. – Andy Turner Aug 31 '19 at 18:21
  • [This short section of the Java Language Specification](https://docs.oracle.com/javase/specs/jls/se11/html/jls-17.html#jls-17.3) explains it quite well. – VGR Sep 01 '19 at 05:23

0 Answers0