Singleton implementation (5039)

Is this singleton implementation correct and thread-safe?

class Class
{
    public static readonly Class Instance;

    static Class()
    {
        Instance = new Class();
    }

    private Class() {}
}

similar: http://answers.unity3d.com/questions/17916/singletons-with-coroutines.html

6 Answers

6

You will probably need to make Class public, and you'd be better off using a property than a readonly variable (Makes it easier to swap how you're implementing the instance later if you need to), but otherwise it's fine

public class Class
{
    private static readonly Class _instance = new Class();
    public static Class Instance { get { return _instance; } }

    static Class(){}

    private Class() {}
}

Another way to do it is using the double check lock pattern, which is a lot faster with multithreaded systems if creation when the instance is accessed is a must:

public class Class
{
    private static volatile Class _instance;
    private static object _lock = new object();

    static Class() {} //Stops the lock being created ahead of time if it's not necessary

    public static Class Instance
    {
        get
        {
            if (_instance == null)
            {
                lock(_lock)
                {
                    if (_instance == null) _instance = new Class();
                }
            }
            return _instance;
        }
    }

    private Class() {}
}

Sure, that code might be thread-safe, but you should always lazy load unless you have a good reason not to.

It's only created when it's used the first time

If you need your singleton to be a MonoBehaviour, then you should look at the answer on this page:

http://answers.unity3d.com/questions/10696/singletons-with-coroutines

which details how you can correctly set up a MonoBehaviour singleton. But if you don't need it to be a MonoBehaviour, then this is the best thread-safe way of doing it:

EDIT: Posted correct code.

class Keyboard : Device
{
    static object _lock = new object();
    public Keyboard Instance
    {
        get
        {
            lock (_lock)
            {
                return _instance ?? _instance = new Keyboard();
            }
        }
    }
    private Keyboard _instance;

    private Keyboard() { }
}

Other way round I'm afraid - your way has issues with threading if two threads access it for the first time simultaneously, while his doesn't

Still the same problem actually (besides the omission of static for the instance function and the variable). If you're doing it this way, _instance has to be volatile, otherwise it's still possible to get a double creation

Thread safe singletons in C#: http://www.yoda.arachsys.com/csharp/singleton.html

Discusses performance and double check locking.

I got a perfect answer on StackOverflow

http://stackoverflow.com/questions/3136008/singleton-implementation-correct

Your question there doesn't even reference thread safety... why would you change your question?

I'm not following you, @SpikeX... And Ferdil, why not accepting your own answer, while bringing what's been suggested there and quoting here?

C#

public class Singleton
{

protected Singleton();

private sealed class SingletonCreator
{
    private static readonly Singleton instance = new Singleton();
    public static Singleton Instance { get { return instance; } }
}

public static Singleton Instance { get { return SingletonCreator.Instance; } }

}

protected Singleton() {} Should it be this?

This is my favourite one so far. To make it thread safe, just use lock as already stated elsewhere:

using UnityEngine;
 
/// <summary>
/// Be aware this will not prevent a non singleton constructor
///   such as `T myT = new T();`
/// To prevent that, add `protected T () {}` to your singleton class.
/// </summary>
public class Singleton<T> : MonoBehaviour where T : MonoBehaviour
{
	private static T _instance;
 
	private static object _lock = new object();
 
	public static T Instance
	{
		get
		{
			if (applicationIsQuitting) {
				Debug.LogWarning("[Singleton] Instance '"+ typeof(T) +
					"' already destroyed on application quit." +
					" Won't create again - returning null.");
				return null;
			}
 
			lock(_lock)
			{
				if (_instance == null)
				{
					_instance = (T) FindObjectOfType(typeof(T));
 
					if ( FindObjectsOfType(typeof(T)).Length > 1 )
					{
						Debug.LogError("[Singleton] Something went really wrong " +
							" - there should never be more than 1 singleton!" +
							" Reopenning the scene might fix it.");
						return _instance;
					}
 
					if (_instance == null)
					{
						GameObject singleton = new GameObject();
						_instance = singleton.AddComponent<T>();
						singleton.name = "(singleton) "+ typeof(T).ToString();
 
						DontDestroyOnLoad(singleton);
 
						Debug.Log("[Singleton] An instance of " + typeof(T) + 
							" is needed in the scene, so '" + singleton +
							"' was created with DontDestroyOnLoad.");
					} else {
						Debug.Log("[Singleton] Using instance already created: " +
							_instance.gameObject.name);
					}
				}
 
				return _instance;
			}
		}
	}
 
	private static bool applicationIsQuitting = false;
	/// <summary>
	/// When Unity quits, it destroys objects in a random order.
	/// In principle, a Singleton is only destroyed when application quits.
	/// If any script calls Instance after it have been destroyed, 
	///   it will create a buggy ghost object that will stay on the Editor scene
	///   even after stopping playing the Application. Really bad!
	/// So, this was made to be sure we're not creating that buggy ghost object.
	/// </summary>
	public void OnDestroy () {
		applicationIsQuitting = true;
	}
}