Fork me on GitHub

Singleton

Motivation

Objects reside inside heap memory, and we can instantiate as many objects as the physical space in the heap memory will allow. But, in some cases, we can have a situation when only one instance of a class can be instantiated. So, imagine that we are developing a program which is playing audio files. Inside that program, we need to have a class which handles audio output. A computer usually has one audio output, so no more than one sound can be played at a time. Therefore, a class that handles the computer audio device should have exactly one instance.

How can we ensure that only one instance is created? Each java class has default public constructor, which can be invoked from any part of the code. If we implement a class where default constructor has scope ‘private’, then only the methods from that class can invoke that constructor, meaning that we can’t instantiate that class from other classes. This is a basis of the Singleton pattern.

The Singleton ensures that only one (single) object can be created from the class.

Story

Men’s 100 meters world record holder is a singleton. There can be only one active “Men’s 100 meters world record holder” at any given time. Regardless of the actual person who holds this title, “Men’s 100 meters world record holder” is a global point of access that identifies the fastest person in the world.

Image

alt text

Brick Lane Graffiti Usain Bolt (CC BY 2.0) by Martin Pettitt

UML

Structure

The fact that every class has a public constructor in Java can be used in order to implement a Singleton. The public constructor will be overridden with a new constructor which does nothing, but the scope of the constructor is private, so other classes can’t instantiate class objects.

The object is created in the method getInstance(), and since an object is created when method getInstance() is invoked for first time, we are talking about lazy instantiation technique.

This technique ensures that singleton instances are created only when needed.

This implementation may have issues in multi-threaded environment, but in such situation we have to synchronize method getInstance(), or put that method inside synchronize block.

In addition to lazy initialization technique, we can have eager initialization technique, where instance is created during class loading. Eager initialization can be implemented using variable static initialization or static block where exception can be handled.

Implementation

Singleton.java

package com.hundredwordsgof.singleton;

/**
 * Singleton class implements singleton pattern. Only one object can be
 * instantiated.
 * 
 */
public class Singleton {

  /**
   * Holds reference to single instance.
   */
  private static Singleton INSTANCE;

  /**
   * Overrides public Constructor.
   */
  private Singleton() {
  }

  /**
   * Creates the instance if it does not yet exist(lazy instantiation).
   * 
   * @return a reference to the single instance.
   */
  public static Singleton getInstance() {
    if (INSTANCE == null) {
      INSTANCE = new Singleton();
    }
    return INSTANCE;
  }
}

Usage

SingletonTest.java

package com.hundredwordsgof.singleton;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import org.junit.Test;

/**
 * Test implementation of the Singleton pattern.
 */
public class SingletonTest {

  @Test
  public void testSingleton() {

    // invokes Singleton.getInstance() for first time,
    // object will be created
    Singleton singleton = Singleton.getInstance();
    assertNotNull(singleton);

    // invokes Singleton.getInstance() for second time,
    // reference to the same object will be returned
    Singleton secondSingleton = Singleton.getInstance();
    assertEquals(singleton, secondSingleton);
  }
}