This article introduces singleton design pattern and its 5 implementation variations (with C#).
Problem
At most one instance of a class must be created in an application.
At most one instance of a class must be created in an application.
Solution
That class (singleton) is defined including its own instance, and the constructor must be private.
That class (singleton) is defined including its own instance, and the constructor must be private.
Implementations
1. Lazy initialization, non-thread safe: This is the classical version, bot it's not thread safe. If more than one thread attempts to access instance at the same time, more than one instance may be created.
public class Singleton {
private static Singleton instance = null;
public static Singleton Instance() {
if (instance == null) {
instance = new Singleton();
}
return instance;
}
private Singleton() {}
}
2. Non-lazy initialization, thread safe: This is the simplest thread safe version, but it does not support lazy initialization.
public class Singleton {
private readonly static Singleton instance = new Singleton();
public static Singleton Instance() {
return instance;
}
private Singleton() {}
}
3. Lazy initialization, thread safe: This version supports both properties, but has performance problems. Once a thread uses singleton instance, the others have to wait because of lock.
public class Singleton {
private static Singleton instance = null;
private static readonly object lockObj = new object();
private static readonly object lockObj = new object();
public static Singleton Instance() {
lock (lockObj) {
lock (lockObj) {
if (instance == null) {
instance = new Singleton();
}
return instance;
}
}
}
private Singleton() {}
}
4. Double-check locking: An improved version of the third solution. Two null controls prevent lock waits for most time, but not always. Also, it does not work properly for Java because of Java memory management approach.
public class Singleton {
private static Singleton instance = null;
private static object lockObj = new object();
private static object lockObj = new object();
public static Singleton Instance() {
if (instance == null) {
lock (lockObj) {
if (instance == null) {
lock (lockObj) {
if (instance == null) {
instance = new Singleton();
}
}
}
return instance;
}
return instance;
}
private Singleton() {}
}
5. Nested initialization: A nested class is used for lazy initialization. This version is also thread safe, but a bit complex. For most situations, solutions 2 or 4 will be suitable according to performance parameters.
public class Singleton {
public static Singleton Instance() {
return Nested.instance;
}
private Singleton() {}
class Nested {
static Nested() {}
internal static readonly Singleton instance = new Singleton();
}
class Nested {
static Nested() {}
internal static readonly Singleton instance = new Singleton();
}
}
Usage:
public static void Main(string[] args)
{
Singleton instance = Singleton.Instance();
}
FYI, this is the actual preferred way to do:
ReplyDeletehttp://stackoverflow.com/questions/70689/efficient-way-to-implement-singleton-pattern-in-java/71399#71399
Can you talk about what benefit or harm each implementation does compared to one or other? Thanks
ReplyDeletere: http://stackoverflow.com/questions/70689/efficient-way-to-implement-singleton-pattern-in-java/71399#71399
ReplyDeleteI think Josh Bloch's enum based Singleton covers only non-lazy initialization and he also points out cases where this approach will not work, e.g. per-thread Singletons
You have missed one most important yet powerful approach of singleton, the enum type.
ReplyDeletePublic enum Foo {
INSTANCE;
}
ref: Effective Java, Joshua Bloch. (Item: ...).
Thanks for examples, viewpoints and suggestions. They will be considered in future posts.
ReplyDeleteIf you are using Spring... that is your answer.
ReplyDeletenice article. just for information, i translated your post into russian. ;)
ReplyDeletehttp://csharpdeveloper.ru/2010/09/21/5-implementations-of-singleton-pattern/
Thanks for translating and referencing our page.
ReplyDeleteI don't see anywhere to instantiate Singleton class in No.5. How does it suppose to work?
ReplyDeleteFixed. Thank you for notification.
ReplyDeleteWhy no reference to this canonical article written in 2006 on Singletons in C#?
ReplyDeletehttp://csharpindepth.com/Articles/General/Singleton.aspx
--jeroen
Nice post , just to add
ReplyDeleteWhile writing Singleton class we need to consider many points e.g.
1) Serialization
2) Many ClassLoaders
3) Cloning
to tackle all above problem best way is to use JAVA 5 Enum functionality and write Singleton using Enum like below.
public enum Singleton {
INSTANCE;
public static void hi(){
System.out.println("Hi");
}
}
Thanks
Javin
Why String is immutable in Java
You have missed one more yet powerful approach of singleton - monotype
ReplyDeletevenu