Does a thread still perceives the constructor's effect as happening after a volatile reference is set to reference the newly created object?

Viewed 70

I read it here-

When thread A writes to a volatile variable and subsequently thread B reads that same variable, the values of all variables that were visible to A prior to writing to the volatile variable become visible to B after reading the volatile variable. So from a memory visibility perspective, writing a volatile variable is like exiting a synchronized block and reading a volatile variable is like entering a synchronized block

The below snippet is taken from here and the article dates back to year 2001 when the semantics of volatile keyword were different.

class SomeClass {
  private Resource resource = null;
  public Resource getResource() {
    if (resource == null) {
      synchronized {
        if (resource == null) 
          resource = new Resource();
      }
    }
    return resource;
  }
}

The Double Checked locking is fixed if the reference is made volatile.

private volatile Resource resource = null;

But do I need to make the member fields of the Resource class as volatile too to ensure thread safety?

EDIT:

The author mentions in the same article that - Volatile doesn't mean what you think, either

A commonly suggested nonfix is to declare the resource field of SomeClass as volatile. However, while the JMM prevents writes to volatile variables from being reordered with respect to one another and ensures that they are flushed to main memory immediately, it still permits reads and writes of volatile variables to be reordered with respect to nonvolatile reads and writes. That means -- unless all Resource fields are volatile as well -- thread B can still perceive the constructor's effect as happening after resource is set to reference the newly created Resource.

That means the Double Checked Locking was fine prior to JDK 5, considering Resource fields are volatile as well or the class itself is immutable. Please suggest.

1 Answers
Related