0

Are both the below approaches for lazy-initializing thread-safe singleton in java correct? Is there any performance difference? If not then why do we use the Holder pattern(Singleton2) instead of keeping it simple as in Singleton1 ?

Thanks in advance.

class Singleton1 {
    private Singleton1() {
        System.out.println("Singleton1-Constructor");
    }

    private static final Singleton1 inst1 = new Singleton1();

    public static Singleton1 getInst1() {
        return inst1;
    }
}

class Singleton2 {
    private Singleton2() {
        System.out.println("Singleton2-Constructor");
    }

    public static class Holder {
        private static final Singleton2 holderInst = new Singleton2();
    }

    public static Singleton2 getInst2() {
        return Holder.holderInst;
    }
}

public class App {
    public static void main(String[] args) {
        Singleton1.getInst1(); // without this statement the Singleton1 constructor doesnt get called.
        Singleton2.getInst2(); // without this statement the Singleton2 constructor doesnt get called.
    }
}
Javadee
  • 139
  • 10
  • Possible duplicate of [What is an efficient way to implement a singleton pattern in Java?](https://stackoverflow.com/questions/70689/what-is-an-efficient-way-to-implement-a-singleton-pattern-in-java) – Slaw Jul 15 '18 at 21:43
  • Your second option, `Singleton2`, allows you to execute other static methods (if there are any) without triggering the construction of an instance. Normally, however, the `Holder` class is `private static` and you expose the instance using a `public static` method on the singleton class. At least that's is how I've always seen it done. – Slaw Jul 15 '18 at 21:48
  • For people who think its duplicate … please look at the explanation provided by Pietro Boido below. Nobody in the suggested post has explained it in the same manner. Some people need a bit more explanation so please do not kill off questions because you think there are similar questions already asked. Thanks, – Javadee Jul 15 '18 at 22:10
  • [This answer to the possible duplicate](https://stackoverflow.com/a/73763/6395627) goes over what Pietro Boido states in his answer. However, I will say that I think Pietro is more direct. – Slaw Jul 15 '18 at 22:19

1 Answers1

2

Singleton1 is not truly lazy, since if you add any other method to Singleton1 and call it from the main class, then the static inst1 will be initialized.

Try this:

public class Singleton1 {
  private Singleton1() {
    System.out.println("Singleton1-Constructor");
  }

  private static final Singleton1 inst1 = new Singleton1();

  public static Singleton1 getInst1() {
    return inst1;
  }

  public static void foo() {
  }
}

public class Singleton2 {
  private Singleton2() {
    System.out.println("Singleton2-Constructor");
  }



  public static class Holder {
    private static final Singleton2 holderInst = new Singleton2();
  }

  public static Singleton2 getInst2() {
    return Singleton2.Holder.holderInst;
  }

  public static void bar() {
  }
}

public class LazyInitializationApp {

  public static void main(String[] args) {
    Singleton1.foo();
    Singleton2.bar();
  }
}

Now running the app will print:

Singleton1-Constructor

But it will not print Singleton2-Constructor, because it is truly lazy.

Pietro Boido
  • 186
  • 5
  • Thanks Pietro Boido for your detailed reply. But from thread safety perspective are both the solutions safe? – Javadee Jul 15 '18 at 22:39