32

I have developed singleton in many ways depending upon the condition like volatile/lazy singleton, eager singleton, normal singleton and through Enum also, but specifically I want to know about static holder pattern singleton shown below.

public static class Singleton {
    private static class InstanceHolder {
        public static Singleton instance = new Singleton();
    }

    private Singleton(){}

    public static Singleton getInstance() { 
        return InstanceHolder.instance;
    }
}

Please advise under which conditions it is beneficial and what are its benefits.

user2094103
  • 685
  • 3
  • 7
  • 14
  • Plenty of questions on this already, but a good reason for not using singletons is difficulty to test. – vikingsteve Feb 22 '13 at 07:56
  • 5
    Your implementation is incorrect. Instance should be final. – jdb Feb 22 '13 at 07:56
  • 3
    Yes, in fact `instance` can actually be `private static final`. – vikingsteve Feb 22 '13 at 08:00
  • 4
    You cannot have a top-level `static` class in Java! You need to change the first line to: `public class Singleton`. See: http://stackoverflow.com/questions/7486012/static-classes-in-java – stackoverflowuser2010 May 27 '16 at 01:54
  • @jdb why? is it mandatory? – naXa stands with Ukraine Sep 09 '16 at 12:03
  • 1
    Any change to instance will not be visible or may publish a partially initialized instance to other threads unless all access is synchronized somehow. If you are not supposed to change it then it should be final. http://docs.oracle.com/javase/specs/jls/se7/html/jls-17.html#jls-17.5 – jdb Sep 13 '16 at 23:14

2 Answers2

77

This pattern is beneficial for at least 3 reasons:

  1. Static factory
  2. Lazy initialization
  3. Thread safe

The JVM defers initializing the InstanceHolder class until it is actually used, and because the Singleton is initialized with a static initializer, no additional synchronization is needed. The first call to getInstance by any thread causes InstanceHolder to be loaded and initialized, at which time the initialization of the Singleton happens through the static initializer.

Static holder pattern is also considered as the smartest replace for Double-check-locking antipattern.

Vladimir Kishlaly
  • 1,872
  • 1
  • 16
  • 26
  • 10
    +1 For actually answering the OPs question of "what are the benefits". – Duncan Jones Aug 29 '14 at 07:29
  • 1
    "and because the Singleton is initialized with a static initializer, no additional synchronization is needed" - I'm curious about this statement. Under the hood, the JVM must be doing synchronization in order to make sure there's no race, right? – bhh1988 May 28 '18 at 02:31
  • @bh1988 - No. The initialisation step happens in a sequential manner hence no synchronisation is needed . – cafebabe1991 May 21 '19 at 12:35
  • @bhh1988 I think that "no additional synchronization is needed" refers to explicitly do syncro as programmer. JVM (classloader) handles that internally. – Petr Újezdský Jul 31 '20 at 10:35
  • The question is why InstanceHolder is loaded later than Singleton - can't understand. Is that а feature of inner class? – Ekaterina Nov 19 '21 at 09:25
  • So it's basically the difference how java initialize static variables and static classes? The static class is guaranteed to be initialized only once, but the variable doesn't? – Kimi Chiu Mar 19 '23 at 07:36
7

This is a way to make a thread-safe lazy singleton by exploiting the way how JVM loads classes. You can read more about why and how to correctly implement it in Bloch's Effective Java book.

Remember, that from the testable code point of view singletons (and global state in general) are not beneficial and should be avoided.

denis.solonenko
  • 11,645
  • 2
  • 28
  • 23