Tuesday, January 10, 2012

Interview Question: What is Singleton pattern and its implementation in C#?

The other day I talked to my college who just came back from interviewing a candidate. During the conversation he mentioned that he asked the candidate to write some code to implement the Singleton pattern. This reminded me an excellent post from Jon Skeet: Implementing the Singleton Pattern in C#.

It is a very common pattern that you might see it everyday, for example, ServiceLocator. For the basic purpose it is simple: the class only only has one instance at a time.

class Singleton
{
    private Singleton()
    {
    }

    private static Singleton _instance;

    public static Singleton Instance
    {
        get
        {
            if (_instance == null)
                _instance = new Singleton();

            return _instance;
        }
    }
}

The implementation does two things:
1. sets the constructor to private thereby nowhere else outside of the class can instantiate the class.
2. exposes an instance of itself by a public static property; if the instance does not exist yet, instantiates one.

If there is only one thread runs the code then this simple implementation is good enough. But when there are multiple threads and concurrency happens multiple threads can jump into the _instance = new Singleton() and create multiple instances thereby violates the pattern's purpose. In this case we just need to add a lock to prevent multiple threads jumping into the line of code.

class Singleton
{
    private Singleton()
    {
    }

    private static Singleton _instance;
    private static readonly object _locker = new object();

    public static Singleton Instance
    {
        get
        {
            lock(_locker)
            {
                if (_instance == null)
                    _instance = new Singleton();

                return _instance;
            }
        }
    }
}

You might be concerned that every time it accesses the instance it locks the locker which is a bit more expensive. But in the commercial projects I have ever done it did not cause any performance issue. If still concerns you then the double-checked locking trick could be helpful (here it is only about C# implementation).

In some cases you might need lazyness. The implementation with Lazy<T> is quite elegant

class Singleton
{
    private Singleton()
    {
    }

    private static Lazy _lazy = new Lazy(() => new Singleton());

    public static Singleton Instance
    {
        get { return _lazy.Value; }
    }
}

and it is thread safe. Lazy<T>() or Lazy<T>(Func<T>) are thread safe because by default it uses LazyThreadSafetyMode.ExecutionAndPublication mode which provides thread safety. It has thread unsafe way though such as Lazy<T>(false) , Lazy<T>(LazyThreadSafetyMode.None) and Lazy<t>(Func<T>, LazyThreadSafetyMode.None). Maybe in single thread application you can use the thread unsafe ones and gain some performance benefits. Other than that I can't think of any real-life situations I need them.

No comments:

Post a Comment