Problem
In other words, is this Singleton implementation thread safe:
public class Singleton
{
private static Singleton instance;
private Singleton() { }
static Singleton()
{
instance = new Singleton();
}
public static Singleton Instance
{
get { return instance; }
}
}
Asked by urini
Solution #1
Before any instances of a class are generated or any static members are accessed, static constructors are guaranteed to be called just once per application domain. https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/classes-and-structs/static-constructors
For the initial building of the Singleton object, the implementation shown is thread safe, which means no locking or null testing is necessary. This does not, however, imply that all uses of the instance will be synchronized. This can be done in a number of ways, one of which I’ve demonstrated here.
public class Singleton
{
private static Singleton instance;
// Added a static mutex for synchronising use of instance.
private static System.Threading.Mutex mutex;
private Singleton() { }
static Singleton()
{
instance = new Singleton();
mutex = new System.Threading.Mutex();
}
public static Singleton Acquire()
{
mutex.WaitOne();
return instance;
}
// Each call to Acquire() requires a call to Release()
public static void Release()
{
mutex.ReleaseMutex();
}
}
Answered by Zooba
Solution #2
There is one caveat to all of these replies, which is that they all give the same broad answer.
It’s important to remember that all possible derivations of a generic class are compiled as separate types. As a result, use caution when using static constructors for generic types.
class MyObject<T>
{
static MyObject()
{
//this code will get executed for each T.
}
}
EDIT:
The following is a demonstration:
static void Main(string[] args)
{
var obj = new Foo<object>();
var obj2 = new Foo<string>();
}
public class Foo<T>
{
static Foo()
{
System.Diagnostics.Debug.WriteLine(String.Format("Hit {0}", typeof(T).ToString()));
}
}
In the console:
Hit System.Object
Hit System.String
Answered by Brian Rudolph
Solution #3
The use of a static constructor is threadsafe. Only one call to the static constructor is guaranteed.
The following is taken from the C# language specification:
Yes, you may be confident that your singleton will be instantiated appropriately.
The static constructor will not guarantee thread-safe shared access to the singleton, as Zooba pointed out (and 15 seconds before me!). That will have to be handled in a different way.
Answered by Derek Park
Solution #4
From the aforementioned MSDN page on c# singleton, here’s the Cliffnotes version:
You can’t go wrong if you follow the pattern below:
public sealed class Singleton
{
private static readonly Singleton instance = new Singleton();
private Singleton(){}
public static Singleton Instance
{
get
{
return instance;
}
}
}
Aside from the obvious singleton functionalities, it also provides you with the following two benefits (in comparison to singletons in C++):
Answered by Jay Juch
Solution #5
Because static constructors are guaranteed to fire just once per App Domain, you should be fine. It is, however, functionally identical to the more condensed, inline version:
private static readonly Singleton instance = new Singleton();
When you’re lazily initializing objects, thread safety becomes more of a concern.
Answered by Andrew Peters
Post is based on https://stackoverflow.com/questions/7095/is-the-c-sharp-static-constructor-thread-safe