Design Patterns in C# & Java : The Singleton.
So its back to reality of living back home! I’ve been slowly going through my mail and replying to everyones messages, one in particular stood out from someone asking me about how to implement the Singleton pattern properly in C# and Java.
First of all, lets go through what the Singleton Design Pattern is and where its used.
Singleton Design Pattern
The Singleton Pattern is quite simply a design pattern that allows only one instance of itself to be created per application pool or application instance and provides one point of access to the single unique instance.
I guess one could conclude that the Singleton is like Neo, it is “the one”. From the Gang of Four – Design Patterns book (the Bible when it comes to talk about commonly used Design Patterns!) the definition or intent of the Singleton pattern is described as:
Ensure a class only has one instance, and provide a global point of access to it.
If you haven’t already got it on your bookshelf, I’d highly recommend buying the book!
Usage
When the Singleton Design Pattern comes in handy is when we want to ensure that a class is instantiated once and optionally in a lazily fashion – when the instance is first accessed, unlike Global variables (bad bad bad!) where it will always consume memory regardless! Alternatively we could opt to have the Singleton class instantiated as soon as the class is loaded which isn’t quite so lazy. How you chose to load it is completely your call based on how ‘heavy’ the load-tax is on the class itself and if there is a performance penalty etc.
Implementation
In order to implement a class as a Singleton object we need to do a few things to make sure we stay consistent:
- The constructor for the class has to be marked private (or protected), this ensures that the class is not able to be instantiated outside itself – compiler-level restriction.
- In C#, mark the class as sealed so that no other classes can “extend” or inherit this Singleton class.
- In Java, override the clone method to ensure that the class is not cloned (as the object class contains a protected _clone_ method).
- Implement an accessor method to allow classes to access this class, usually Instance() in C# or _getInstance() _in Java.
- In a multi-threaded application, ensure that the checking and instantiating initially is mutually exclusive (thread-safe). This is easily accomplished in C# and in Java 5+ as we will see soon.
There are two ways to implement the loading of the class, one is to instantiated it as soon as the class itself is loaded and the other lazily loaded when another class needs to use it (avoiding loading it before-hand).
Implementations – Java Bare-Essential (Non-Thread Safe)
So lets look at how to implement the pattern in Java first. Initially the plain bare-essential version which does not factor in thread-safety at all and uses Lazy-loading.
public class Singleton {
protected Singleton() {}
private static Singleton _instance = null;
/**
* @return The unique instance to this class.
*/
public static Singleton getInstance() {
if (null == _instance) {
_instance = new Singleton();
}
return _instance;
}
/**
* To avoid an inherted class from trying to
* clone the class, we override the object.clone
* method and throw an exception.
*/
public Object clone() throws CloneNotSupportedException {
throw new CloneNotSupportedException();
}
}
Implementations – Java Thread Safe
Now how about a thread-safe implementation we add the synchronized keyword into the method declaration as per Java coding standard.
/**
* @return The unique instance to this class.
*/
public static synchronized Singleton getInstance() {
if (null == _instance) {
_instance = new Singleton();
}
return _instance;
}
But if your using Java 5, there is yet another way which uses volatile double checked locking as described on Wikipedia, however using this prior to Java 5 is not recommended as it is broken.
A simpler and more effective way is to use a subclass to hold the instance safely, this ensures that the class is only loaded when the getInstance() method is called (Lazy-loaded) and no earlier. Here we declare a class called SingletonContainer to hold a single static final variable that has an instance of the class Singleton. The JVM will only create an instance of Singleton when getInstance() is called.
public class Singleton {
protected Singleton() {}
/**
* SingletonHolder is loaded on the first execution of Singleton.getInstance()
* or the first access to SingletonHolder.instance , not before.
*/
private static class SingletonContainer {
private final static Singleton _instance = new Singleton();
}
public static Singleton getInstance() {
return SingletonContainer._instance;
}
public Object clone() throws CloneNotSupportedException {
throw new CloneNotSupportedException();
}
}
Implementations – C# Bare-Essentials
Moving onto a C# version, first up is a bare-essentials version based on our original list of points needed to implement the Singleton object.
public sealed class Singleton
{
private static Singleton _Instance = null;
private Singleton() { }
public static Singleton Instance
{
get
{
if (null == _Instance)
{
_Instance = new Singleton();
}
return _instance;
}
}
}
Easy done, but as mentioned earlier this is _not_ thread-safe.
Implementations – C# Thread-Safe
Lets work on a thread-safe version using a lock. This ensures that all reads happen logically after a lock is acquired and unlocking that all writes happen logically before release.
public sealed class Singleton
{
private static Singleton _Instance = null;
private static readonly object _Lock = new object ();
private Singleton() { }
public static Singleton Instance
{
get
{
lock (_Lock)
{
if (null == _Instance)
{
_Instance = new Singleton();
}
return _instance;
}
}
}
}
What about a thread-safe version without the use of a lock? Sure, quite possible in .NET with the use of the readonly keyword.
Const vs ReadOnly fields in C#
Lets step back a bit and go into the readonly keyword first. The readonly keyword is often mixed with the const keyword, but whilst they may seem to do the samething they offer very different ways of achieving the final result, a read-only field. A const field can only be initialised when declared (compile-time constant) where as a readonly field can be initialised either at declaration time or in the constructor of the class. This is a very important distinction as a readonly field means that it may be different each time the class is loaded, where as a const field is always going to be the same unless you change the constant and recompile the assembly.
Implementations – C# Thread-Safe readonly
OK back to the C# Thread-Safe version this time without locks using the readonly keyword.
public sealed class Singleton
{
private static readonly Singleton _Instance = new Singleton();
private Singleton() { }
public static Singleton Instance
{
get
{
return _Instance;
}
}
}
So when this class is loaded by the CLR, the _Instance variable is initialised and a new instance is created. Therefore when the Instance method is invoked we know that it will always exist.
Implementations – C# Thread-Safe Lazy-Loading readonly
Finally, an implementation that uses Lazy-Loading to enhance the previous version one more time!
public sealed class Singleton
{
private Singleton() { }
public static Singleton Instance
{
get
{
return SingletonContainer._Instance;
}
}
class SingletonContainer
{
static SingletonContainer() { }
internal static readonly Singleton _Instance = new Singleton();
}
}
So there we have it, some examples and usage of Singletons in different situations. For optimal use, one should document whether having a lazy-loaded or class-loading solution is beneficial. I tend to use the threadsafe readonly version (class loading) more than usual.