Pages

Wednesday, August 25, 2010

5 Implementations of Singleton Pattern




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.
Solution
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();
    public static Singleton Instance() {
        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();
    public static Singleton Instance() {
        if (instance == null) {
            lock (lockObj) {
                if (instance == null) {
                    instance = new Singleton();
                }
            }
        }
        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()
    }
}

Usage: 
public static void Main(string[] args)
{
    Singleton instance = Singleton.Instance();
}


13 comments:

  1. FYI, this is the actual preferred way to do:
    http://stackoverflow.com/questions/70689/efficient-way-to-implement-singleton-pattern-in-java/71399#71399

    ReplyDelete
  2. Can you talk about what benefit or harm each implementation does compared to one or other? Thanks

    ReplyDelete
  3. re: http://stackoverflow.com/questions/70689/efficient-way-to-implement-singleton-pattern-in-java/71399#71399

    I 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

    ReplyDelete
  4. You have missed one most important yet powerful approach of singleton, the enum type.

    Public enum Foo {
    INSTANCE;
    }

    ref: Effective Java, Joshua Bloch. (Item: ...).

    ReplyDelete
  5. Thanks for examples, viewpoints and suggestions. They will be considered in future posts.

    ReplyDelete
  6. If you are using Spring... that is your answer.

    ReplyDelete
  7. nice article. just for information, i translated your post into russian. ;)
    http://csharpdeveloper.ru/2010/09/21/5-implementations-of-singleton-pattern/

    ReplyDelete
  8. Thanks for translating and referencing our page.

    ReplyDelete
  9. I don't see anywhere to instantiate Singleton class in No.5. How does it suppose to work?

    ReplyDelete
  10. Fixed. Thank you for notification.

    ReplyDelete
  11. Why no reference to this canonical article written in 2006 on Singletons in C#?
    http://csharpindepth.com/Articles/General/Singleton.aspx

    --jeroen

    ReplyDelete
  12. Nice post , just to add
    While 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

    ReplyDelete
  13. You have missed one more yet powerful approach of singleton - monotype

    venu

    ReplyDelete