About me
Services
Projects
Design Patterns
Archive
Contact

The Singleton Pattern

I have always loved the Singleton Pattern. Not sure exactly why, but I have always got a cheap thrill out of using it whenever I can. Could be the fact it was the first Pattern I ever figured out, or it could be because it provides a sense of order, but more than likely, it's because of my love of Singleton Whisky. If you used the pattern you could rest assured that there would be one and only one instance of your class. This is great for things like global preferences and pooling.

I wanted to write a brief page about the Singleton Pattern, outlining one of the situations when I have used it. When I started reading more about the pattern I discovered its nasty little secrets. Unless you implement it correctly, you can't be assured of only one instance.

In order to keep myself sane I decided I had better educate myself. What was the problem with my Singleton? How could I ensure I only ever got one instance, through multi-threading, garbage collectors, and different JVM's?

The Singleton Defined

Intent: Ensure a class has one instance, and provide a global point of access to it. -GoF

An example of a simple Singleton Pattern in java.

   public class Singleton {
      
      
private static Singleton _singleton;
      
      
private Singleton() {}
      
      
public static Singleton getInstance() {
          
if (_singleton == null) {
              
_singleton = new Singleton();
          
}
          
return _singleton;
      
}
   }

The main thing to note in this code example is the Singleton has no public constructor, so you cant instantiate the Singleton class. The only way to get an instance of the Singleton is to call the getInstance() method. The other noteworthy item is that the Singleton is instantiated lazily. The class gets instaniated with the first call to the getInstance method. All subsequent calls will return the one and only one instance of Singleton. And because the getInstance() method is public and static, it can be called from anywhere in your code. How does the Singleton get reloaded? Restart your application.

Multithreading

The problem with the example code above is that it is not thread safe. Specifically portions of the following method are not thread safe,

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

The mutithreading problem occurs when the getInstance() method is called for the first time. Specifically, when mutliple threads access the if condition, this may result in multiple instances of the Singleton class.

The easy solution is to synchronize the getInstance method. This is ok if this particular singleton is not going to be accessed very often. Synchronization does have a huge overhead, it can slow the call to the synchronized method by a factor of 100. So, if your singleton is only going to be called a handful of times through the course of 1000 concurrent users in a day, then dont worry about it, synchronize.

   public static synchronized Singleton getInstance() {
Multithreading under heavy load.

What if your Singleton is going to be called a lot during the course of a day, by 1000 concurrent users? Then synchronization of the getInstance() method will cause a problem, you need to apply a different solution.

The easiest solution is to eliminate the lazy loading in the getInstance() method. Create the instance of the singleton as a static member.

 public class Singleton {
    
    
private static Singleton _singleton = new Singleton();
    
    
private Singleton() {}
    
    
public static Singleton getInstance() {
        
return _singleton;
    
}
 }
Performance

I ran each of these scenarios through 1 billion iterations and here are the results.

Singleton with lazy loading:3600 ms
Synchronized Singleton:20500 ms
Singleton as static member:2600 ms


Keep in mind that my test singleton was small so instantiating it cost very little and I didnt record the startup times either. The first call to the singleton could be a concern if the singleton was a large class that did a lot of stuff on instantiation. But in order to have a threadsafe singleton, you are better off creating the singleton as a static member. It will be instantiated on the first call to getInstance().

Notice the difference between the lazy loaded Singleton and the Singleton as a static member is about 1 second. Just having to check if the instance is null adds 40% to the time spent in the getInstance method.

Double Check locking

There has been a lot written about the problems with the double-check locking idiom. Rather than re-iterate it here, I am going to list a few references.

  1. When is a Singleton not a Singleton? -Joshua Fox, Jan 2001
  2. Double check locking and the Singleton pattern -Peter Haggar, May 2002
Conclusion

The singleton can be thread safe, providing you create it correctly. The solution is not to get wrapped up in lazy loading of the singleton, implement it as a static member. And don't use double-check locking, you can't guarantee that it is going to work.

Good luck!
Copyright 2008 Graham Lange All rights reserved
SUBSCRIBE