Implementation Variants of Singleton Pattern


Singleton is one of the most common design patterns, but it has many implementation variants: lazy Instantiation, eager Instantiation, static holder idiom, and etc. Static holder idiom is my favorite.

package org.codeexample.jefferyyuan.javacode.singletons;

import java.io.Serializable;

public class SinletonVariants {}

/**
 * When the singleton class is referenced, its instance would not be created,
 * and also Java guarantees that the class initialization is atomic.
 * 
 * So using the static holder idiom, we combine the benefit of lazy
 * instantiation and no further synchronization after the instance is created,
 * 
 * My favorite, always use this one.
 */
class SingletonHolderIdiom {
  private SingletonHolderIdiom() {}
  
  private static class SingletonHolder {
    private static final SingletonHolderIdiom instance = new SingletonHolderIdiom();
  }
  
  public static SingletonHolderIdiom getInstance() {
    return SingletonHolder.instance;
  }
}

/**
 * To maintain the singleton guarantee, you have to declare all instance fields
 * transient and provide a readResolve method that directly return the static
 * instance, also you must use eager instantiation.
 * 
 * see Effective Java 2nd Edition: Item 3: Enforce the singleton property with a
 * private constructor or an enum type
 */
class SerializableSingleton implements Serializable {
  private static final long serialVersionUID = 1L;
  private static SerializableSingleton instance = new SerializableSingleton();
  
  private SerializableSingleton() {}
  
  public static SerializableSingleton getInstance() {
    return instance;
  }
  
  // readResolve method to preserve singleton property
  private Object readResolve() {
    return instance;
  }
}

/**
 * This variant avoids the drawback of eager instantiation, as no resources are
 * allocated before the instance is actually accessed, but further
 * synchronization might seem unnecessary and expensive after the instance is
 * already constructed.
 * 
 */
class SingletonLazyInstantiation {
  private static SingletonLazyInstantiation instance;
  
  private SingletonLazyInstantiation() {}
  
  public static synchronized SingletonLazyInstantiation getInstance() {
    if (instance == null) {
      instance = new SingletonLazyInstantiation();
    }
    return instance;
  }
}

/**
 * This would initialize this singleton class eagerly, when the class is loaded
 * at first time. Thus, it may happen that the singleton instance is constructed
 * even if it is not accessed. This is a drawback, especially when the
 * construction is complex and time/resource consuming. The good part of this
 * variant is its simplicity.
 * 
 */
class SingletonEagerInstantiation {
  private static SingletonEagerInstantiation instance = new SingletonEagerInstantiation();
  
  private SingletonEagerInstantiation() {}
  
  public static SingletonEagerInstantiation getInstance() {
    return instance;
  }
}

Labels

adsense (5) Algorithm (69) Algorithm Series (35) Android (7) ANT (6) bat (8) Big Data (7) Blogger (14) Bugs (6) Cache (5) Chrome (19) Code Example (29) Code Quality (7) Coding Skills (5) Database (7) Debug (16) Design (5) Dev Tips (63) Eclipse (32) Git (5) Google (33) Guava (7) How to (9) Http Client (8) IDE (7) Interview (88) J2EE (13) J2SE (49) Java (186) JavaScript (27) JSON (7) Learning code (9) Lesson Learned (6) Linux (26) Lucene-Solr (112) Mac (10) Maven (8) Network (9) Nutch2 (18) Performance (9) PowerShell (11) Problem Solving (11) Programmer Skills (6) regex (5) Scala (6) Security (9) Soft Skills (38) Spring (22) System Design (11) Testing (7) Text Mining (14) Tips (17) Tools (24) Troubleshooting (29) UIMA (9) Web Development (19) Windows (21) xml (5)