Friday, 25 September 2015

GoF: Singleton Pattern

Description

The Singleton Pattern is one the fundamental design patterns described by the Gang Of Four (GoF) in the volume “Design patterns – Elements of reusable object-oriented software”.

It is a creational pattern whose purpose is to make sure that of a particular class one instance, and only one instance, can be created, offering a global access point to that instance to all clients requesting it.




Simple implementation (no thread-safe)

public class Singleton {
    private static Singleton instance = null;
 
    // The constructor is private: the creation of instances must be controlled.
    // private Singleton () {}
 
    // This method is used to obtain the unique instance of this class, creating it 
    // if necessary.
    public static Singleton getMySingleton () {
        if (instance == null) {
            instance = new Singleton();
        }
        return instance;
    }
}

Notice that the constructor of this class is private, because the creation of instances must be controlled, making sure that only one instance is created. Instances of the Singleton class cannot be created outside this class.
To obtain an instance of the Singleton class we use the method getMySingleton(). The first time this method is invoked a new instance of the class is created (instance == null); subsequently (instance != null) the same instance is returned, making sure that only one instance of this class is created and returning it to all clients requesting it.

Thread-safe implementation: synchronized

public class MySingleton {
    // volatile makes sure that changes are immediately visible to all threads.
    private volatile static Singleton instance = null;
 
    // The constructor is private: the creation of instances must be controlled.
    private MySingleton() {}
 
    // This method is used to obtain the unique instance of this class, in a 
    // thread-safe manner, creating it if necessary.
    public static Singleton getMySingleton() {
        if (instance == null) {
            // Only this part of the code must be synchronized, because the 
            // variable “instance” is of type volatile.
            synchronized (MySingleton.class){
              // I’m not sure to be the first thread to access this method
              if (instance == null)
                 instance = new Singleton();
            }
        }
        return instance;
    }
}
There are two main things to notice here:
  1. the synchronization is placed after checking that instance == null (first creation of the object): for subsequent accesses there is no need to do this, because the same instance previously created is simply returned to all clients requesting it (in this case there is no need of synchronization).
  2. after the synchronization we have to check again that instance == null. To understand this imagine that two different threads (thread 1 and thread 2) enter this method for the first time (instance == null). The first thread that enters the synchronized block (thread 1) creates the unique instance of this class and returns it. Then the second thread (thread 2) enters the same synchronized block, but this time the unique instance of the class has already been created (instance != null and thread 2 knows it for sure, because the variable “instance” is of type volatile). So no new instances must be created and the method simply returns the unique instance already created by thread 1.

Thread-safe implementation: implicit (Java)

In Java when a class is initialized and loaded into memory for the first time all its static variables are also initialized, and this operation is thread-safe by default.
We can leverage this feature to implement the Singleton Pattern in a thread-safe way…

public class Singleton { 
    /**
    * When this class is loaded into memory the constant INSTANCE is created, and this 
    * operation is thread-safe.
    */
   private final static Singleton INSTANCE = new Singleton();
 
  /**
   * The constructor is private: the creation of instances must be controlled.
   */
  private Singleton() {}
 
  /**
   * Access point to the Singleton.
   */
  public static Singleton getInstance() {
    return INSTANCE;
  }
}


Thread-safe implementation: lazy initialization (Java)

public class Singleton { 
   /**
   * The constructor is private: the creation of instances must be controlled.
   */
  private Singleton() {}
 
  /**
   * The class Container is initialized/loaded into memory when getInstance() is
   * is invoked for the first time, that is when Container.INSTANCE is accessed for
   * the first time and in a thread-safe way.
   */
  private static class Container { 
    private final static Singleton ISTANCE = new Singleton();
  }
 
  /**
   * Accesso point to the Singleton. It makes sure that the constant INSTANCE is created
   * only one time (Singleton) and only when this method is invoked, not before.
   */
  public static Singleton getInstance() {
    return Container.INSTANCE;
  }
}

The last implementation was first introduced by Bill Pugh and uses the so called “lazy initialization”. The idea is to create the unique instance of the Singleton class only when really needed, namely when the method getInstance() is invoked, and not before (in the “Tread-safe implementation: implicit” implementation, that we have seen before, the instance is immediately created when the class is initialized and loaded into memory).  The trick is to create an inner class, Container, containing our Singleton instance. The Singleton instance is created when we refer to the inner class for the first time, that is when the method getInstance is invoked, and not when the outer class is initialized and loaded into memory like in the previous implementation.

No comments:

Post a Comment