Tuesday, January 1, 2013

Singleton - the good, the bad & the ugly

Well, lets just jump in, for the ones don't know what a Singleton is here is a short desc:

The Goal

  • Make sure a certain class has only one instance, and provide a global point of access to it.
  • Implement “just-in-time initialization” or “initialization on first use”, meaning DO NOT initialize the class before we specifically asked for, and do so only on the 1st time. 
  • Encapsulate it for god sake! 

The Implementation

    Shell we start with the ugly

    Why is this ugly? well first because it being use as the typical interview question everybody likes to ask & everybody knows how to answer, second these code snippet is only good from Java 5+ which means all your legacy code won't be able to use it due to a stupid JVM bug allowing the instance reference to be returned before the Singleton constructor is executed.
    Last - those are way to many lines of code using synchronization, locking, volatile (will need a new post only to explain that one...) when all we wanted is a simple implementation...
     
    public class Singleton {
      private static volatile Singleton instance = null;
     
      private Singleton() {       }
     
      public static Singleton getInstance() {
        if (instance == null) {
          synchronized (Singleton.class){
            if (instance == null) {
              instance = new Singleton();
            }
          }
        }
        return instance;
      }
    }

    Let's move on with the bad, well, compare to the other ones :-)
    So this one goes straight forwards, but this time uses a static block which is too many lines of code to do such a simple task, also it may seduce us to write some additional code in it.

    A Lazy initialization implementation
    public class Singleton {
      private static final Singleton instance;
     
      static {
        try {
          instance = new Singleton();
        } catch (IOException e) {
          throw new RuntimeException("An error occurred!", e);
        }
      }
     
      public static Singleton getInstance() {
        return instance;
      }
     
      private Singleton() {
        // Do something here...
      }
    }
    
    
    An eager initialization implementation (rarely being used as we prefer to be lazy & save memory & CPU)
    public class Singleton {
      private static final Singleton instance = new Singleton();
     
      private Singleton() {}
     
      public static Singleton getInstance() {
        return instance;
      }
    }
    
    
    So we came to the good, or maybe the nice & clean, so simple that when you look at it at the first time, it takes couple of minute to even understand what is going on there, so take couple of minutes before you read the explanation below & try to figure it out by yourselves.
    
    
    public class Singleton {
      private Singleton() { }
       
      private static class SingletonHolder { 
        public static final Singleton INSTANCE = new Singleton();
      }
     
      public static Singleton getInstance() {
        return SingletonHolder.INSTANCE;
      }
    }
    • The nested class is referenced only once & no earlier (and therefore loaded no earlier by the class loader) than the moment that getInstance() is Called.
    • Thus, this solution is thread safe without requiring special language constructs (violate or synchronized) and has lazy initialization.
    • Work on any Java version
    No go & fix your code :-)

    3 comments:

    1. An additional approach is the Enum approach as suggested by Joshua Bloch the "Effective Java" writer.
      http://stackoverflow.com/questions/70689/what-is-an-efficient-way-to-implement-a-singleton-pattern-in-java

      ReplyDelete