Home | FAQ | Contact me

The Singleton pattern in Java


Skip to the on-demand holder pattern.

The Singleton Pattern, one of the patterns defined by the Gang of 4, restricts the instantiation of a class to a single object. It's useful to coordinate actions across an entire system, access to a hardware interface, logger, configuration file, cache, etc.

Pros and cons of the Single Pattern

Pros

Cons

Inside this code

In terms of beginning Java samples you have the implementation of a singleton. This is the simplest form, but it would be disastrous in a multithreaded situation. (See the second article for solutions to questions like this.)

public class Singleton
{
  // holds but one instance of this class
  private static Singleton instance;

  // private constructor prevents any callers from instantiating
  private Singleton()
  {
    System.out.println( "Constructing new instance of Singleton..." );
  }

  // provide public access to the single instance
  public static Singleton getInstance()
  {
    // lazy initialization...
    if ( instance == null )
      instance = new Singleton();

    return instance;
  }

  public void print()
  {
    System.out.println( "Inside singleton!" );
  }
}

"Early" initialization

If it's not important to construct the class instance lazily, it's possible to let Java handle its construction ahead of time. This would be thread-safe in most situations. Modern Java thought is that there is no real advantage to lazy initialization in preference to "early" initialization unless there is a very real possibility that the class will simply never be instantiated. Here's the preferred, "early" version.

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

  private Singleton()
  {
    System.out.println( "Constructing new instance of Singleton..." );
  }

  public static Singleton getInstance()
  {
    if ( instance == null )
      instance = new Singleton();

    return instance;
  }

  public void print()
  {
    System.out.println( "Inside singleton!" );
  }
}

Thread-safe, lazy initialization

Here's how to spruce it up to be thread-safe, using the synchronized keyword.

public class Singleton
{
  private static Singleton instance;

  private Singleton()
  {
    System.out.println( "Constructing new instance of Singleton..." );
  }

  public static Singleton getInstance()
  {
    synchronized( Singleton.class )
    {
      if( instance == null )
        instance = new Singleton();
    }

    return instance;
  }

  public void print()
  {
    System.out.println( "Inside singleton!" );
  }
}

Trying to finesse it...

Goetz' Java Concurrency In Practice (pp. 348,9) says double-locking isn't good practice and since at least Java 5, the JVM start-up speed is no longer so slow as to make lazy initialization of an object that's going to be used an important consideration.

Bracketing the synchronization (double-locking) in a check for null instance (instead of proceeding directly with the used of synchronized) hoping for the advantage of reducing the use and overhead of Java synchronization to just the first time object instantiation is contested (and satisfied) so it will not be a burden again in the life of the (singleton) object would only work reliably beginning in Java 5 AND with the use of the volatile keyword on the static instance.

  private volatile static Singleton instance;
      .
      .
      .
  public static Singleton getInstance()
  {
    if( instance == null )
    {
      synchronized( Singleton.class )
      {
        if( instance == null )
          instance = new Singleton();
      }

      return instance;
  }

Thwarting the singleton...

If the class is cloned, however, there will be another instance of it. The only way to prevent that would be to override clone and throw an exception.

import java.lang.CloneNotSupportedException;

  .
  .
  .

  @Override
  public Object clone()
  {
    throw new CloneNotSupportedException( "Singleton-only; no cloning!" );
  }
}

It would still be possible to serialize/deserialize and get a non-unique instance. To prevent that, the class could be made an enumeration and Java would prevent it.

The "initialization-on-demand holder" idiom

...what Wikipedia calls this, anyway. This is how I began to code singletons at some point.

This is a pattern augmenting the singleton that is formally designed to improve lazy loading. It works in single- or serial- as well as concurrent (multithreaded) situations. Its trick is to implement an inner class to perform initialization based on the specified initialization phase of execution in the JVM.

Then the outer or principal class is loaded by the JVM, it's initialized. Since, unlike most traditional singleton implementations, there are no static variables, this first initialization does little to nothing.

On first initialization of Something, the holder inner class is not initialized right off. This only happens the first time a calling application thread happens to wander through the outer class' getInstance() method. Only at that point will the JVM load and initialize SomethingHolder. Since the class initialization phase is guaranteed by the Java Language Specification to be strictly serial, which is to say, not concurrent, no explicit synchronization is necessary for getInstance(). Since the JVM writes the variable INSTANCE in this serial operation, all subsequent invocations of getInstance(), concurrent or not, will return precisely the correctly initialized INSTANCE without additional or explicit synchronization overhead.

Disadvantages

This version of the singleton might be avoided if the construction of INSTANCE is likely to fail, but failure to initialize is a criticism of singleton pattern implementations in general.

Example

In the code below, what's in bold is where the traditional singleton implementation is rejoined. Notice that Something's constructor remains private. It's called only by the holder class. The private constructor can do some real things as exemplified by the later real-world example.

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

  private Something() { }

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

  .
  .
  .
}

A real-world example...

...of a data-access object class implementing accounts in a MongoDB database. This shows a more, useful, real-world context in the implementation.

AccountDao.java:
public class AccountDao extends BaseDao< Account >
{
  private static final Logger log = Logger.getLogger( AccountDao.class );

  private MongoDB   mongoDB;
  private Datastore datastore;

  private static class AccountDaoHolder
  {
    public static final AccountDao INSTANCE = new AccountDao();
  }

  private AccountDao()
  {
    mongoDB   = new MongoDB( "accountdb", "accounts" );
    datastore = mongoDB.getMorphiastore();
  }

  public static AccountDao getInstance()
  {
    log.trace( "AccountDao getInstance()" );
    return AccountDaoHolder.INSTANCE;
  }

  public DBCollection     getCollection() { return mongoDB.getCollection(); }
  public Datastore        getDatastore()  { return datastore; }
  public Class< Account > getClazz()      { return Account.class; }

  public Account create( Account entity )
  {
    datastore.save( entity );
    return entity;
  }

  public List< Account > findByIdentity( String identity )
  {
    Query< Account > query = datastore.createQuery( Account.class )
                                  .filter( "identities", identity );
    return query.asList();
  }

  public List< Account > readAll()
  {
    Query< Account > query = datastore.createQuery( Account.class );

    query.field( "canceled" ).equals( false );
    return query.asList();
  }

  .
  .
  .
}