Java Programming Tutorials

Java programming tutorials with many code examples!

Java Singleton – on demand initialization

Java Singleton – on demand initialization

On demand initialization is extension of static final implementation. It will prevent eager initialization of the singleton instance, when other fields are accessed. Also known as Bill Pugh‘s solution.

How it works

The SingletonOnDemand will be our Singleton with its only instance hidden inside the SingletonHolder. The class loading mechanism guarantees that on the first access to SingletonOnDemand class all its fields will be initialized, but not fields from the inner static class, because it is another class.

To initialize the singleton instance we have to call getInstance() method that will access the INSTANCE field inside SingletonHolder class, triggering initialization process of the nested static class.

public class SingletonOnDemand {

    private SingletonOnDemand() {}

    private static class SingletonHolder {
        public static final SingletonOnDemand INSTANCE
            = new SingletonOnDemand();
    }

    public static SingletonOnDemand getInstance() {
        return SingletonHolder.INSTANCE;
    }
}

Properties of this implementation:

  • works in all known versions of Java,
  • instantiated only on the first access to getInstance(), hence SingletonHolder.INSTANCE,
  • thread-safe without any additional language constructs,
  • thanks to the getter can easily be extended to more than one instance,
  • easy to implement.

Complete example

In the following example we will access to the FORMAT field, which will initialize SingletonOnDemand class, but won’t initialize it’s singleton instance, because it is hidden in a separate, nested class:

package com.farenda.patterns.singleton;

public class SingletonOnDemand {

    public static final String FORMAT = "Format: '%s'";

    private SingletonOnDemand() {
        System.out.println("Instantiating Singleton...");
    }

    private static class SingletonHolder {
        // will be initialized only when getInstance() is called
        public static final SingletonOnDemand INSTANCE
            = new SingletonOnDemand();
    }

    public static SingletonOnDemand getInstance() {
        return SingletonHolder.INSTANCE;
    }
}

Let’s see how the above Singleton implementation works:

package com.farenda.patterns.singleton;

public class StaticFinalExample {

    public static void main(String[] args) {
        System.out.println("Accessing FORMAT field: "
                + SingletonOnDemand.FORMAT);
        System.out.println("Now calling SingletonOnDemand.getInstance():");
        if (SingletonOnDemand.getInstance()
                == SingletonOnDemand.getInstance()) {
            System.out.println("The same instance!");
            System.out.printf("%s == %s%n",
                    SingletonOnDemand.getInstance(),
                    SingletonOnDemand.getInstance());
        } else {
            System.out.println("It's not a Singleton!");
        }
    }
}

The above code produces the following output:

Accessing FORMAT field: Format: '%s'
Now calling SingletonOnDemand.getInstance():
Instantiating Singleton...
The same instance!
SingletonOnDemand@63947c6b == SingletonOnDemand@63947c6b

When we access the FORMAT field nothing happens, because the field actually holding the Singleton is hidden inside another (nested, but still it’s a different class), that will have its static fields initialized only on the first access to it.

References:

Share with the World!