Click here to Skip to main content
Click here to Skip to main content

How Do You Structure Your Singletons?

, 1 Aug 2013
Rate this:
Please Sign up or sign in to vote.
How to structure your Singletons.

Background

I'll skip over the discussion about why many people hate singletons (that's a whole separate can of worms, but worth mentioning) because in the end, it's not going to get rid of them. A singleton is a design pattern that ensures only one instance of the singleton object can ever be constructed. Often, singletons are made to be "globally accessible" in an application (although, I'm still not confident that this is actually part of the definition of a singleton). There are a handful of different ways to implement singletons... so what are they?

The Not-Thread-Safe-Singleton

With singletons, the main goal is to ensure that only one instance can be created. Below is a snippet of singleton code that works, but is not guaranteed in a multi-threaded environment:

internal class NotThreadSafeSingleton
{
    private static NotThreadSafeSingleton _instance;

    /// <summary>
    /// Prevents a default instance from being created.
    /// </summary>
    private NotThreadSafeSingleton()
    {
    }

    /// <summary>
    /// Gets the singleton instance (not thread safe).
    /// </summary>
    internal static NotThreadSafeSingleton Instance
    {
        get
        {
            if (_instance == null)
            {
                _instance = new NotThreadSafeSingleton();
            }

            return _instance;
        }
    }
}

The key take away point here is that if this singleton class is accessed across multiple threads, it is possible that two threads perform the null check and begin the constructor at the same time. Because this block of code is not protected with a lock a race condition occurs.

The Thread-Safe Singleton

If the key problem with the first example was that it is not safe across threads due to lack of locking... Then it should be pretty obvious that we just need to lock!

internal class ThreadSafeSingleton
{
    private static readonly object _instanceLock = new object();
    private static ThreadSafeSingleton _instance;

    /// <summary>
    /// Prevents a default instance of the class from being created.
    /// </summary>
    private ThreadSafeSingleton()
    {
    }

    /// <summary>
    /// Gets the singleton instance (thread safe).
    /// </summary>
    internal static ThreadSafeSingleton Instance
    {
        get
        {
            if (_instance == null)
            {
                lock (_instanceLock)
                {
                    if (_instance == null)
                    {
                        _instance = new ThreadSafeSingleton();
                    }
                }
            }

            return _instance;
        }
    }
}

That looks sort of weird though, doesn't it? The double-check serves two purposes: a required check for thread safety and a performance optimization! The check inside of the lock actually guarantees that a single instance is created across threads. However, the check outside is an optimization because after the first instance is created, there's overhead to acquiring the lock just to check if the instance exists.

For what it's worth, this is actually my preferred method of coding singletons. I've been coding them like this for a while in C#, and I find they work nicely. However, I stumbled upon a posting by John Skeet (essentially, a programming god) who's done a much better job at documenting singleton patterns than I have. In his analysis, he actually notes some drawbacks to this pattern. Firstly, he mentions it doesn't work in Java, which is a great point. I primarily code in C#, but this is still important to acknowledge. Secondly, he calls upon ECMA CLI memory specifications that state it's not guaranteed to actually be thread safe without memory barriers. This was slightly out of my comfort zone, so I admit I still have yet to look into this. Finally, I do agree that the pattern is easy to get wrong for more junior developers and as for performance, I've never considered it an issue at all. (Hopefully by now you've come back from his write-up to finish mine!)

Generic Singleton: A Quick Hand At It...

One of the big drawbacks I saw with the thread safe singleton implementation that I favour is the amount of boilerplate code. Every time I want a new singleton class, I have to code basically everything you see in the previous section. It's redundant and I don't want to do it. I can hear the singleton-haters saying "so STOP making them!" but as I said, that's a discussion for a later post.

I decided I'd have a quick attempt at making a generic singleton! Check out my implementation below (and be warned that I flipped some condition checks in order to try and reduce the width of the text to fit nicely here...):

internal class Singleton<T> where T : class
{
    private static readonly object _instanceLock = new object();
    private static T _instance;

    /// <summary>
    /// Prevents a default instance of the class from being created.
    /// </summary>
    private Singleton()
    {
    }

    /// <summary>
    /// Gets the singleton instance (thread safe).
    /// </summary>
    internal static T Instance
    {
        get
        {
            if (_instance != null)
            {
                return _instance;
            }

            lock (_instanceLock)
            {
                if (_instance != null)
                {
                    return _instance;
                }

                const string SINGLETON_EXCEPTION_MSG =
                        "A single private parameterless constructor is required.";

                var constructors = typeof(T).GetConstructors(
                    BindingFlags.Public |
                    BindingFlags.CreateInstance |
                    BindingFlags.Instance);

                if (constructors.Length > 0)
                {
                    throw new Exception(SINGLETON_EXCEPTION_MSG);
                }

                constructors = typeof(T).GetConstructors(
                    BindingFlags.NonPublic |
                    BindingFlags.CreateInstance |
                    BindingFlags.Instance);

                if (constructors.Length != 1 ||
                    constructors[0].GetParameters().Length > 0 ||
                    !constructors[0].IsPrivate)
                {
                    throw new Exception(SINGLETON_EXCEPTION_MSG);
                }

                _instance = (T)constructors[0].Invoke(null);
                return _instance;
            }
        }
    }
}

Doesn't look to shabby, right? You simply need to create a class with *only* a private constructor and everywhere you want access to the singleton, you say Singleton<MyType>.Instance. It's that easy.

Unfortunately, this isn't as good as I initially hoped. Can you think of an example where this approach breaks down? My hint to you is everything you need to break it is posted right here. Unfortunate really because I thought I was onto something good there! Smile | :) In reality, it may not be a bad foundation for your singleton implementations if you don't like the boiler plate code I listed above.

Summary

There are many ways to write singletons, and some are clearly more robust than others. I've only shown you a couple here, but John Skeet's post has a handful more which he prefers. It's hard to argue with what he's written (although, I'm not actually fond of his fourth implementation which he likes) because he's done a great analysis on them. In the end, it's important to know what a singleton actually is, when you might want to use it, and what the differences actually mean in various implementations.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

Share

About the Author

Nick Cosentino
Team Leader Magnet Forensics
Canada Canada
I graduated from the University of Waterloo for Computer Engineering and I'm fortunate enough to work as a Team Lead of Software Engineering at Magnet Forensics. As a team lead, I'm often looking to encourage better coding standards, creative approaches to problem solving, and ensure that good clean code makes it into the code base. I want my team to produce top-notch code, but I want to make sure that we're all learning to become better developers along the way.
 
Blog: http://www.devleader.ca
Facebook: https://www.facebook.com/DevLeaderCa
LinkedIn: http://www.linkedin.com/in/nickcosentino
Twitter: http://www.twitter.com/nbcosentino
Google+: https://plus.google.com/+DevleaderCa/posts
Follow on   Twitter   Google+   LinkedIn

Comments and Discussions

 
SuggestionNo need for reflection PinprofessionalRichard Deeming12-Aug-13 8:15 
GeneralRe: No need for reflection PinmemberNick Cosentino12-Aug-13 8:44 
QuestionEager?! PinmemberArash M. Dehghani8-Aug-13 9:55 
SuggestionLazy<T> does the trick ? Pinmembermike7530-Jul-13 11:01 
GeneralRe: Lazy<T> does the trick ? PinmemberNick Cosentino30-Jul-13 11:10 
GeneralThoughts PinprofessionalPIEBALDconsult24-Jul-13 7:58 
GeneralRe: Thoughts PinmemberNick Cosentino24-Jul-13 8:32 
GeneralRe: Thoughts PinprofessionalPIEBALDconsult24-Jul-13 8:45 
GeneralRe: Thoughts PinmemberNick Cosentino24-Jul-13 9:58 
GeneralRe: Thoughts PinprofessionalPIEBALDconsult24-Jul-13 10:00 
GeneralRe: Thoughts PinmemberNick Cosentino24-Jul-13 11:42 
QuestionError in code example PinmemberBermin24-Jul-13 6:07 
AnswerRe: Error in code example PinmemberNick Cosentino24-Jul-13 6:10 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

| Advertise | Privacy | Mobile
Web03 | 2.8.140821.2 | Last Updated 1 Aug 2013
Article Copyright 2013 by Nick Cosentino
Everything else Copyright © CodeProject, 1999-2014
Terms of Service
Layout: fixed | fluid