Intro to Java Singleton Pattern

This entry is part 12 of 13 in the series Intro to Java

The last pattern we looked at was the Adapter pattern. It was a good pattern to start with as it maps well to the physical world and is fairly simple. Now we will look at the Singleton pattern. In some respects it is the simplest of patterns, but there are some things to think about.

The Singleton in the Physical World

The idea behind the Singleton is to ensure that there can be only one (insert Highlander jokes here). If you had a factory that made widgets, you would want a widget to be created many many times. But there is only one factory. If you were modeling the US government, you would only want one president. Only one senate.

The Singleton in the Software World

On the software side, the idea is the same. It is usually used when we only want one set of configuration variables, one controller, one data base connection pool, that kind of thing.

How do we do this?

Let’s back up a bit. Let us look at a very basic class that provides us with a code that is needed across our application.

public class MyClass {

   private long code;

   public MyClass() {
      code = Calendar.getInstance().getTimeInMillis();
   }

   public long getCode() {
      return code;
   }
}
public class MyClassTest {
   public static void main(String[] args) throws Exception {

      MyClass myClass1 = new MyClass();
      System.out.println(myClass1.getCode());

      Thread.sleep(500);// wait a bit to see if our code is the same

      MyClass myClass2 = new MyClass();
      System.out.println(myClass2.getCode());

      System.out.println("Oops. Different values.");
   }
}

If you only ever instantiated this class once, you are fine. But we haven’t done anything here to ensure that this is the case. There is nothing to stop someone from creating two MyClass objects.

Let’s start with the opposite. How do we create an instance of a class?

MyClass myClass1 = new MyClass();
MyClass myClass2 = new MyClass();

What can we do to ensure that only one instance can be created? Is there something else we have looked at that allows only one instance of a variable to occur? Static! We can use the static property.

public class MyStaticClass {

   private static long code = Calendar.getInstance().getTimeInMillis();

   public static long getCode() {
      return code;
   }
}
   public static void main(String[] args) throws Exception {

      MyStaticClass myClass1 = new MyStaticClass();
      System.out.println(MyStaticClass.getCode());
      System.out.println(myClass1);

      Thread.sleep(500);// wait a bit to make sure our code is the same

      MyStaticClass myClass2 = new MyStaticClass();
      System.out.println(MyStaticClass.getCode());
      System.out.println(myClass2);

      System.out.println("Ok. Same values.");
      System.out.println("Oops, different objects.");

   }
}

This time we have assigned a static variable our code, and provided a static method for accessing this code. Does this work? Somewhat. We only have one instance of code inside of MyStaticClass, but MyStaticClass is not guaranteed to have only one instance. This will get cumbersome to initialize as we add other data. It also results in a bunch of MyStaticClass.getCode() all over the application. What would be better would be to ask for this class just once, and then call getCode() as needed. How can we set that up?

The Simplest Singleton

public class Singleton {

   private static Singleton singleton;

   private Singleton() {
   }

   public static Singleton getInstance() {
      if ( singleton == null ) {
         singleton = new Singleton();
      }
      return singleton;
   }
}

This example doesn’t have our “code” in it, but it does show the elements of the singleton. We will add the “code” later.

There are some interesting things about this class. Look at the constructor. It is private! How does that work? We can’t do a “new” on this class! How can we create it? There is a private member variable that is static, and is of the same type as the class! It is a very strange sight at first glance. What is going on?

The constructor being private accounts for our first goal. No ability to call “new” on the object. If we can’t do a “new”, how can we create it? Well, we can do a “new”, but only from inside the class itself. We are doing that in the static getInstance() method. Look at what that method does. It first checks to see if an instance of the member variable singleton exists. If it doesn’t, it creates a “new” instance. This is the only place we will ever create an instance of the class Singleton. Therefore we have ensured that this is the only copy available. We then return singleton.

By doing things this way we have also lazy initialized the singleton. If we don’t need it, we never call getInstance(), and we never have to worry about the JVM allocating memory for something not used.

We also get a normal looking class out of it. We can have standard getters that are not static, and our application can pass this object around. It is easier to conceptualize the object used this way, and do maintenance later than a bunch of static methods seemingly randomly called within methods.

Can we actually do something?

Ok, I get your point. We need a bit more of an example. So here is a singleton with one “code” just like the others.

public class MySingletonClass {

   private static MySingletonClass singleton;

   private long code;

   private MySingletonClass() {
      code = Calendar.getInstance().getTimeInMillis();
   }

   public static MySingletonClass getInstance() {

      if ( singleton == null ) {
         singleton = new MySingletonClass();
      }
      return singleton;
   }

   public long getCode() {
      return code;
   }
}
public class MySingletonClassTest {
   public static void main(String[] args) throws Exception {

      MySingletonClass mySingletonClass1 = MySingletonClass.getInstance();
      System.out.println(mySingletonClass1.getCode());
      System.out.println(mySingletonClass1);

      Thread.sleep(500); //wait a bit to make sure our code is the same

      MySingletonClass mySingletonClass2 = MySingletonClass.getInstance();
      System.out.println(mySingletonClass2.getCode());
      System.out.println(mySingletonClass2);

      System.out.println("yea, same code");
      System.out.println("yea, same object");
   }
}

Look at that. Other than the singleton field, the constructor marked as private, and the getInstance() method, it is a pretty normal looking class. The constructor initializes our class just as we would expect. We can have pretty standard fields, like “code” with normal public getters.

Is that all there is to it?

Yup. It is that easy. Almost. Sometimes. There is one more wrinkle. Depending on how this singleton is being used, you may need to account for multiple threads. I am not going to get into that here, as we haven’t looked at threads yet. Keep in mind that if multiple objects could all call getInstance() at the same time, you may have an issue. Look it up, or wait and see if I get to threads eventually 😉

Why use the pattern?

  • Ensures only one instance of your code with minimal fuss.
  • The singleton can be assigned.
  • Uses lazy initialization to save memory.
  • It is proven. It works. You can try to avoid the pattern, but why bother?
Series NavigationIntro to Java Adapter PatternIntro to Java Decorator Pattern