Question

it is mentioned in the Java Memory Model that: When a thread exits a synchronized block as part of releasing the associated monitor, the JMM requires that the local processor cache be flushed to main memory. Similarly, as part of acquiring the monitor when entering a synchronized block, local caches are invalidated so that subsequent reads will go directly to main memory and not the local cache.

so why in that code I must declare instance as volatile since when the second thread enters the synch block will go directly to main memory ??

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

I mean when another thread enters synch block and make the second check it is supposed to update from main memory as mentioned.

Was it helpful?

Solution

The race condition is this:

  1. Thread A sees instance == NULL and is running this code instance = new MySingleton();. The write to instance is visible but the writes into MySingleton are not yet.

  2. Thread B sees instance != NULL and starts working on instance.

  3. Thread B is now working on an object whose construction it cannot see.

Making instance volatile solves the problem as the JDK memory specification, as of JDK5, guarantees that writes to non-volatile objects will not be seen out of order with respect to a write to a volatile object. So any thread that sees instance != NULL must see the instance itself.

OTHER TIPS

You have to declare it volatile otherwise there is no guarantee that two calls to getInstance() will return the same instance.

There is no guarantee that main memory will be accessed, only a cache-consistent value. i.e. all threads will see the same value.

BTW: You know of course its far more complex than needed. All you need is

public enum MySingleton {
     INSTANCE;
}

does much the same thing.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top