3

I came across a singleton class {lazy initialization}. The code is as below

// Singleton reference for this class
    private static volatile FileProperties INSTANCE = null; 

    public static FileProperties getInstance() {
            if (INSTANCE == null) {
                synchronized (FileProperties.class) {
                    if (INSTANCE == null) {
                        INSTANCE = new FileProperties();
                    }
                }
            }
            return INSTANCE;
        }

My question is what is the benefit we are getting by making INSTANCE as volatile Since we already taking care of thread safety by synchronized. Is there any benefit of volatile in this scenario ?

Sean Patrick Floyd
  • 292,901
  • 67
  • 465
  • 588
sorabh solanki
  • 480
  • 1
  • 7
  • 18

1 Answers1

5

That is because double-checked locking without volatile is not thread-safe in Java.

The simplest way to make thread-safe lazy-init singleton is to create class holder as follows:

public class SomeClass {
    private static class SomeClassHolder {
        public static final SomeClass INSTANCE = new SomeClass();
    }

    public static SomeClass getInstance() {
       return SomeClassHolder.INSTANCE;
    } 

    private SomeClass() {}

}

That part of code, because of JVM behavior will load SomeClassHolder and create an instance of SomeClass on first usage of getInstance() (and not when SomeClass is loaded by classloader).

You don't need to use any synchronization at all!! Because JVM is doing it for you.

Michal Borek
  • 4,584
  • 2
  • 30
  • 40
  • double checked locking has been threadsafe since the introduction of "happens before" implication of `volatile` (Java 1.5). Also, you're missing a private constructor – Bohemian May 14 '13 at 11:59
  • 1
    DCL *is* thread-safe in Java from Java 1.5 onwards, so long as you *also* use `volatile`. (I wouldn't use it myself, but it's thread-safe.) – Jon Skeet May 14 '13 at 12:00
  • @Bohemian: `volatile` was in Java from 1.0, I believe. Properly-implemented DCL has been thread-safe since the memory model changes in 1.5. – Jon Skeet May 14 '13 at 12:00
  • 1
    Thanks guys, but not without a keyword `volatile` and that is what the answer was about. – Michal Borek May 14 '13 at 12:01
  • @JonSkeet Yep, you're right. From 1.5 onwards, "happens before" was enforced. Cheers. – Bohemian May 14 '13 at 12:03
  • @MichalBorek: The answer doesn't state that at all - it doesn't even *mention* the word `volatile`, and it refers to an article referring to an old version of the memory model. – Jon Skeet May 14 '13 at 12:04