Initialization-on-demand holder idiom

from Wikipedia, the free encyclopedia

In software development , the design pattern Initialization on Demand Holder describes an implementation option of a so-called lazy-initialized singleton , i.e. an implementation in which the object is only initialized when it is used for the first time. In all Java versions it allows a secure, highly parallelizable lazy initialization with good performance.

functionality

The following example shows an implementation of the idiom:

public class Something {
    private Something() {}

    private static class LazyHolder {
        private static final Something INSTANCE = new Something();
    }

    public static Something getInstance() {
        return LazyHolder.INSTANCE;
    }
}

It is based on the initialization phase of execution within the Java Virtual Machine (JVM), as described in the Java Language Specification (JLS). When the class Something is loaded by the JVM, it goes through the initialization process. Since the class does not have to initialize any static variables , the initialization process is completed immediately. The static class definition LazyHolderwithin the class is not initialized until the JVM recognizes that the class is LazyHolderneeded and needs to be executed. The static class LazyHolderonly runs when the static method is used getInstance in the class Something. The first time the method is called, the JVM loads and initializes the class LazyHolder. The initialization of the class also LazyHolderresults in the initialization of the static variable INSTANCEwhich calls the (private) constructor of the enclosing class Something. Since the initialization phase of a class is guaranteed to run serially, i.e. not in parallel, according to JLS, no further synchronization is getInstancenecessary in the static method during loading and initialization. Since the initialization phase describes the static variable INSTANCEin a serial operation, all parallel calls to the getInstancemethod INSTANCEreturn the same, correctly initialized variable .

This results in a highly efficient, thread-safe “singleton” cache, with no additional synchronization effort; Benchmarks showed that this implementation is significantly faster than many others with synchronization. Nonetheless, this idiom is singleton-specific and cannot be extended to multi-object classes.

Just one opportunity to initialize

Despite the elegance of this approach (which was first described by Pugh), any error during the initialization of the class results in an unusable state of the holder class, which means that this approach should only be used if the developer is certain that the initialization cannot fail. Example:

public class PughFail {
    public static class Something {
        private Something() {
            super();
            System.out.println(this.getClass().getName() + " called");
            if (System.currentTimeMillis() > 0) {
                System.out.println("EMULATING INIT FAILURE");
                throw new RuntimeException("EMULATING INIT FAILURE");
            }
        }
        private static class LazyHolder {
            private static final Something INSTANCE = new Something();
        }
        public static Something getInstance() {
            return LazyHolder.INSTANCE;
        }
    }
    public static void main(String[] args) {
        System.out.println("First try");
        try {
            Something.getInstance();
        } catch (Throwable t) {
            System.out.println(t);
        }
        System.out.println("Second try");
        try {
            Something.getInstance();
        } catch (Throwable t) {
            System.out.println(t);
        }
    }
}

Output:

First try
PughFail$Something called
EMULATING INIT FAILURE
java.lang.ExceptionInInitializerError
Second try
java.lang.NoClassDefFoundError: Could not initialize class PughFail$Something$LazyHolder

See also

Web links

Individual evidence

  1. The Double Checked Locking Idiom does not work correctly in versions prior to Java 1.5.
  2. 12.4 of Java Language Specification.
  3. Fastest Thread-safe Singleton in the JVM . In: literatejava.com .