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; }
}
}
Static constructors are guaranteed to be run only once per application domain, before any instances of a class are created or any static members are accessed. https://learn.microsoft.com/en-us/dotnet/csharp/programming-guide/classes-and-structs/static-constructors
The implementation shown is thread safe for the initial construction, that is, no locking or null testing is required for constructing the Singleton object. However, this does not mean that any use of the instance will be synchronised. There are a variety of ways that this can be done; I've shown one below.
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();
}
}
While all of these answers are giving the same general answer, there is one caveat.
Remember that all potential derivations of a generic class are compiled as individual types. So use caution when implementing static constructors for generic types.
class MyObject<T>
{
static MyObject()
{
//this code will get executed for each T.
}
}
EDIT:
Here is the 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
Using a static constructor actually is threadsafe. The static constructor is guaranteed to be executed only once.
From the C# language specification:
The static constructor for a class executes at most once in a given application domain. The execution of a static constructor is triggered by the first of the following events to occur within an application domain:
An instance of the class is created.
Any of the static members of the class are referenced.
So yes, you can trust that your singleton will be correctly instantiated.
Zooba made an excellent point (and 15 seconds before me, too!) that the static constructor will not guarantee thread-safe shared access to the singleton. That will need to be handled in another manner.
Here's the Cliffnotes version from the above MSDN page on c# singleton:
Use the following pattern, always, you can't go wrong:
public sealed class Singleton
{
private static readonly Singleton instance = new Singleton();
private Singleton(){}
public static Singleton Instance
{
get
{
return instance;
}
}
}
Beyond the obvious singleton features, it gives you these two things for free (in respect to singleton in c++):
lazy construction (or no construction if it was never called)
synchronization
Static constructors are guaranteed to fire only once per App Domain so your approach should be OK. However, it is functionally no different from the more concise, inline version:
private static readonly Singleton instance = new Singleton();
Thread safety is more of an issue when you are lazily initializing things.
The static constructor will finish running before any thread is allowed to access the class.
private class InitializerTest
{
static private int _x;
static public string Status()
{
return "_x = " + _x;
}
static InitializerTest()
{
System.Diagnostics.Debug.WriteLine("InitializerTest() starting.");
_x = 1;
Thread.Sleep(3000);
_x = 2;
System.Diagnostics.Debug.WriteLine("InitializerTest() finished.");
}
}
private void ClassInitializerInThread()
{
System.Diagnostics.Debug.WriteLine(Thread.CurrentThread.GetHashCode() + ": ClassInitializerInThread() starting.");
string status = InitializerTest.Status();
System.Diagnostics.Debug.WriteLine(Thread.CurrentThread.GetHashCode() + ": ClassInitializerInThread() status = " + status);
}
private void classInitializerButton_Click(object sender, EventArgs e)
{
new Thread(ClassInitializerInThread).Start();
new Thread(ClassInitializerInThread).Start();
new Thread(ClassInitializerInThread).Start();
}
The code above produced the results below.
10: ClassInitializerInThread() starting.
11: ClassInitializerInThread() starting.
12: ClassInitializerInThread() starting.
InitializerTest() starting.
InitializerTest() finished.
11: ClassInitializerInThread() status = _x = 2
The thread 0x2650 has exited with code 0 (0x0).
10: ClassInitializerInThread() status = _x = 2
The thread 0x1f50 has exited with code 0 (0x0).
12: ClassInitializerInThread() status = _x = 2
The thread 0x73c has exited with code 0 (0x0).
Even though the static constructor took a long time to run, the other threads stopped and waited. All threads read the value of _x set at the bottom of the static constructor.
The Common Language Infrastructure specification guarantees that "a type initializer shall run exactly once for any given type, unless explicitly called by user code." (Section 9.5.3.1.) So unless you have some whacky IL on the loose calling Singleton::.cctor directly (unlikely) your static constructor will run exactly once before the Singleton type is used, only one instance of Singleton will be created, and your Instance property is thread-safe.
Note that if Singleton's constructor accesses the Instance property (even indirectly) then the Instance property will be null. The best you can do is detect when this happens and throw an exception, by checking that instance is non-null in the property accessor. After your static constructor completes the Instance property will be non-null.
As Zoomba's answer points out you will need to make Singleton safe to access from multiple threads, or implement a locking mechanism around using the singleton instance.
Although other answers are mostly correct, there is yet another caveat with static constructors.
As per section II.10.5.3.3 Races and deadlocks of the ECMA-335 Common Language
Infrastructure
Type initialization alone shall not create a deadlock unless some code
called from a type initializer (directly or indirectly) explicitly
invokes blocking operations.
The following code results in a deadlock
using System.Threading;
class MyClass
{
static void Main() { /* Won’t run... the static constructor deadlocks */ }
static MyClass()
{
Thread thread = new Thread(arg => { });
thread.Start();
thread.Join();
}
}
Original author is Igor Ostrovsky, see his post here.
Just to be pedantic, but there is no such thing as a static constructor, but rather static type initializers, here's a small demo of cyclic static constructor dependency which illustrates this point.
Static constructor is guaranteed to be thread safe.
Also, check out the discussion on Singleton at DeveloperZen:
http://web.archive.org/web/20160404231134/http://www.developerzen.com/2007/07/15/whats-wrong-with-this-code-1-discussion/
The static constructor is locked. While the type initializer is running, any other thread which attempts to access the class in such a way that would trigger the type initializer will block.
However, the thread which is running the type initializer can access uninitialized static members. So be sure not to call Monitor.Enter() (lock(){}) or ManualResetEventSlim.Wait() from a type initializer if it is run from a UI thread—those are “interruptible” waits which result in the event loop running, executing arbitrary other parts of your program while your type initializer is still unfinished.
It is preferable for you to use managed blocking rather than unmanaged blocking. WaitHandle.WaitOne, WaitHandle.WaitAny, WaitHandle.WaitAll, Monitor.Enter, Monitor.TryEnter, Thread.Join, GC.WaitForPendingFinalizers, and so on are all responsive to Thread.Interrupt and to Thread.Abort. Also, if your thread is in a single-threaded apartment, all these managed blocking operations will correctly pump messages in your apartment while your thread is blocked:
Related
I've been going through the singleton pattern, but I'm not understanding how the below code is thread safe:
public class ThreadSafeSingleton
{
private ThreadSafeSingleton()
{
}
public static ThreadSafeSingleton Instance
{
get { return Nested.instance; }
}
private class Nested
{
static Nested()
{
}
internal static readonly ThreadSafeSingleton instance = new ThreadSafeSingleton();
}
}
Why is this thread-safe?
The CLR executes static constructors only once. It is specified to do so. Therefore, instance is being initialized exactly once. That makes this thread-safe.
How the thread-safety is achieved is an implementation detail.
Please find below implementation for thread safe singleton implementation.
Also, you can use this question useful. It provides double locking thread safety which doesn't hurt performance.
Find reference for static here
Find the reference here
The below code is not thread-safe. Two different threads could both have evaluated the test if (instance==null) and found it to be true, then both create instances, which violates the singleton pattern. Note that in fact the instance may already have been created before the expression is evaluated, but the memory model doesn't guarantee that the new value of instance will be seen by other threads unless suitable memory barriers have been passed.
Not thread safe singleton
// Bad code! Do not use!
public sealed class Singleton
{
private static Singleton instance=null;
private Singleton()
{
}
public static Singleton Instance
{
get
{
if (instance==null)
{
instance = new Singleton();
}
return instance;
}
}
}
Thread safe implementation:
public sealed class Singleton
{
private static Singleton instance = null;
private static readonly object padlock = new object();
Singleton()
{
}
public static Singleton Instance
{
get
{
lock (padlock)
{
if (instance == null)
{
instance = new Singleton();
}
return instance;
}
}
}
}
This implementation is thread-safe. The thread takes out a lock on a shared object, and then checks whether or not the instance has been created before creating the instance. This takes care of the memory barrier issue (as locking makes sure that all reads occur logically after the lock acquire, and unlocking makes sure that all writes occur logically before the lock release) and ensures that only one thread will create an instance (as only one thread can be in that part of the code at a time - by the time the second thread enters it,the first thread will have created the instance, so the expression will evaluate to false). Unfortunately, performance suffers as a lock is acquired every time the instance is requested.
I have a class which has 3 static members. Each of static member is not thread-safe singleton.
I need to provide a thread safe implementation for their use.Is it ok?Or I need to provide thread-safe wrapper for each of them? If I should - how can I do it using Lazy<T>?
Additional question : Measure() and Do() of SingeltonClass1/2/3 are not thread-safe is func1() thread-safe?
public class MyLazySingleton
{
// static holder for instance, need to use lambda to construct since constructor private
private static readonly Lazy<MyLazySingleton> _instance
= new Lazy<MyLazySingleton>(() => new MyLazySingleton());
// private to prevent direct instantiation.
private MyLazySingleton()
{
s_c1 = SingletonClass1.Instance();
s_c2 = SingletonClass2.Instance();
s_c3 = SingletonClass3.Instance();
}
// accessor for instance
public static MyLazySingletonInstance
{
get
{
return _instance.Value;
}
}
public void func1()
{
if (s_s1.Measure() || s_c2.Measure())
{
c_c3.Do();
}
}
static SingletonClass1 s_c1 = null;
static SingletonClass1 s_c2 = null;
static SingletonClass1 s_c3 = null;
}
How should I re-implement MyLazySingleton if its constructor should get 2 arguments? string str and int i
I have asked a follow up question Thread-safe methods in the singleton class
It's thread-safe as it is.
The default value for Lazy<T>'s LazyThreadSafetyMode is ExecutionAndPublication.
From the MSDN page on the new Lazy<T>(Func<T>) constructor:
An instance that is created with this constructor may be used
concurrently from multiple threads.
The thread safety mode of a Lazy instance that is initialized with
this constructor is LazyThreadSafetyMode.ExecutionAndPublication.
If you were to use another overload where you could pass a different LazyThreadSafetyMode value it wouldn't be thread safe. But using the constructor as you are now, it is thread safe.
EDIT: Regarding your additional edited question, if those methods on your SingletonClass1 type are not thread safe: then no, func1 is not thread safe either.
From the Lazy<T> MSDN Page:
Making the Lazy object thread safe does not protect the lazily
initialized object. If multiple threads can access the lazily
initialized object, you must make its properties and methods safe for
multithreaded access.
You will need to make sure that those methods/interactions between those classes are thread safe. This might be as simple as wrapping the func1 body with a lock statement, but I can't say for certain depending on how your 3 instances of SingletonClass1 interact with each other or how calling code may access them.
To ensure Thread-safety you have to set the LazyThreadSafetyMode parameter of the Lazy<T> constructor. There are 3 available values:
None: not thread-safe
PublicationOnly: many MyLazySingleton instance may be created, but only one will be published/returned by the Value property. Internally it uses Interlocked.CompareExchange
ExecutionAndPublication: The value is create only once
Here's an example:
new Lazy<Test>(() => new Test(), LazyThreadSafetyMode.ExecutionAndPublication)
I know there are lot of ways to implement a thread safe singleton pattern like (Double Check Locking , static readonly method, lock method) but i just tried below code
static void Main(string[] args)
{
for (int i = 0; i <= 100; i++)
{
Thread t = new Thread(new ParameterizedThreadStart(doSome));
t.Start(null);
}
Console.ReadLine();
}
private static void doSome(object obj)
{
MyReadOnly obj1 = MyReadOnly.getInstance;
Console.WriteLine(obj1.GetHashCode().ToString());
}
class MyReadOnly
{
private static MyReadOnly instance = new MyReadOnly();
int counter = 0;
// static MyReadOnly()
// {
// } treat is as commented code.
public static MyReadOnly getInstance { get { return instance; } }
private MyReadOnly()
{
Console.WriteLine((++counter).ToString());
}
}
when i see the output of this program , i see just single object created (because of same hashcode)
how to prove that this code is not thread safe?
EDIT
removing static constructor which causes some confusion
That code is thread-safe due to the nature of type initializers in .NET. The type initializer is guaranteed to run exactly once, and if two threads try to run it at the same time, one will do so and the other will block.
See my article on singleton implementation for more details.
This is actually thread-safe code because you are (indirectly) using static constructor to create the instance (And CLR guarantees invocation of static constructor is thread-safe manner on/before access to any other type member).
Another question on SO inspired me to try this code in C#:
class Program
{
static Program()
{
new Program().Run();
}
static void Main(string[] args) { }
void Run()
{
System.Console.WriteLine("Running");
}
}
This prints "Running" when run.
I actually expected the compiler to complain about this. After all, if the class has not yet been initialized by the static constructor; how can we be sure that it is valid to call methods on it ?
So why does the compiler not restrict us from doing this ? Is there any important usage scenarios for this ?
Edit
I am aware of the Singleton pattern; the point in question is why I can call a method on the instance before my static constructor finishes. So far JaredPar's answer has some good reasoning about this.
It is allowed because not allowing it would be a lot worse. Code like this would deadlock badly:
class A {
public static readonly A a;
public static readonly B b;
static A() {
b = new B();
a = B.a;
}
}
class B {
public static readonly A a;
public static readonly B b;
static B() {
a = new A();
b = A.b;
}
}
You are of course pointing a loaded gun at your foot.
This behavior is documented in the CLI Spec (Ecma 335) Partition II, Chapter 10.5.3.2 "Relaxed guarantees":
A type can be marked with the attribute beforefieldinit (§10.1.6) to indicate that the guarantees specified in §10.5.3.1 are not necessarily required. In particular, the final requirement above need not be provided: the type initializer need not be executed before a static method is called or referenced.
[Rationale: When code can be executed in multiple application domains it becomes particularly expensive to ensure this final guarantee. At the same time, examination of large bodies of managed code have shown that this final guarantee is rarely required, since type initializers are almost always simple methods for initializing
static fields. Leaving it up to the CIL generator (and hence, possibly, to the programmer) to decide whether this guarantee is required therefore provides efficiency when it is desired at the cost of consistency guarantees.
end rationale]
The C# compiler indeed emits the beforefieldinit attribute on a class:
.class private auto ansi beforefieldinit ConsoleApplication2.Program
extends [mscorlib]System.Object
{
// etc...
}
Slightly different question.
How would the compiler prevent you from doing this?
Sure it's very easy to detect in your sample, but what about this sample?
class Program {
static void Fun() {
new Program();
}
static Program() {
Fun();
}
}
The ways in which you can trick the compiler to allow this are virtually endless. Even if the compiler got all of the answers you could still beat it with reflection.
In the end though this is actually legal, if a bit dangerous, code in both C# and IL. It is safe to do this as long as you are careful about accessing static's from within this code. It also is helpful / possibly necessary for certain patterns like Singleton's
Static constructor can initialize only static class members, this is not related to class instances and regular non-static class members.
What you may not realize is that for every class that does not have a non-static constructor, the compiler will generate one. This is different from your static constructor, which when you boil it down into MSIL is little more than a flag telling the CLR "Hey, run this code before you run what's in main()". So, the code of your static constructor is executed first. It instantiates a locally-scoped Program object using the NON-static constructor generated behind the scenes, and once instantiated, Run() is called on the object. Then, because you haven't stored this new object anywhere, it is disposed of when the constructor finishes executing. The main() function then runs (and does nothing).
Try this expansion:
class Program
{
static Program()
{
new Program().Run();
}
public Program()
{
Console.WriteLine("Instantiating a Program");
}
public override void Finalize()
{
Console.WriteLine("Finalizing a Program");
}
static void Main(string[] args) { Console.WriteLine("main() called"); }
void Run()
{
System.Console.WriteLine("Running");
}
}
See what the output is. My guess is that it will look something like this:
Instantiating a Program
Running
Finalizing a Program
main() called
The last two lines may be swapped because garbage collection may not get the chance to destroy the instance before main starts running (GC runs in a seperate managed thread, and so it works on its own time within the lifetime of the process), but the instance IS local to the static constructor in scope, and so is marked for collection before main() starts running. So, if you called Thread.Sleep(1000) in main() before printing the message, GC should collect the object in that time.
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; }
}
}
Static constructors are guaranteed to be run only once per application domain, before any instances of a class are created or any static members are accessed. https://learn.microsoft.com/en-us/dotnet/csharp/programming-guide/classes-and-structs/static-constructors
The implementation shown is thread safe for the initial construction, that is, no locking or null testing is required for constructing the Singleton object. However, this does not mean that any use of the instance will be synchronised. There are a variety of ways that this can be done; I've shown one below.
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();
}
}
While all of these answers are giving the same general answer, there is one caveat.
Remember that all potential derivations of a generic class are compiled as individual types. So use caution when implementing static constructors for generic types.
class MyObject<T>
{
static MyObject()
{
//this code will get executed for each T.
}
}
EDIT:
Here is the 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
Using a static constructor actually is threadsafe. The static constructor is guaranteed to be executed only once.
From the C# language specification:
The static constructor for a class executes at most once in a given application domain. The execution of a static constructor is triggered by the first of the following events to occur within an application domain:
An instance of the class is created.
Any of the static members of the class are referenced.
So yes, you can trust that your singleton will be correctly instantiated.
Zooba made an excellent point (and 15 seconds before me, too!) that the static constructor will not guarantee thread-safe shared access to the singleton. That will need to be handled in another manner.
Here's the Cliffnotes version from the above MSDN page on c# singleton:
Use the following pattern, always, you can't go wrong:
public sealed class Singleton
{
private static readonly Singleton instance = new Singleton();
private Singleton(){}
public static Singleton Instance
{
get
{
return instance;
}
}
}
Beyond the obvious singleton features, it gives you these two things for free (in respect to singleton in c++):
lazy construction (or no construction if it was never called)
synchronization
Static constructors are guaranteed to fire only once per App Domain so your approach should be OK. However, it is functionally no different from the more concise, inline version:
private static readonly Singleton instance = new Singleton();
Thread safety is more of an issue when you are lazily initializing things.
The static constructor will finish running before any thread is allowed to access the class.
private class InitializerTest
{
static private int _x;
static public string Status()
{
return "_x = " + _x;
}
static InitializerTest()
{
System.Diagnostics.Debug.WriteLine("InitializerTest() starting.");
_x = 1;
Thread.Sleep(3000);
_x = 2;
System.Diagnostics.Debug.WriteLine("InitializerTest() finished.");
}
}
private void ClassInitializerInThread()
{
System.Diagnostics.Debug.WriteLine(Thread.CurrentThread.GetHashCode() + ": ClassInitializerInThread() starting.");
string status = InitializerTest.Status();
System.Diagnostics.Debug.WriteLine(Thread.CurrentThread.GetHashCode() + ": ClassInitializerInThread() status = " + status);
}
private void classInitializerButton_Click(object sender, EventArgs e)
{
new Thread(ClassInitializerInThread).Start();
new Thread(ClassInitializerInThread).Start();
new Thread(ClassInitializerInThread).Start();
}
The code above produced the results below.
10: ClassInitializerInThread() starting.
11: ClassInitializerInThread() starting.
12: ClassInitializerInThread() starting.
InitializerTest() starting.
InitializerTest() finished.
11: ClassInitializerInThread() status = _x = 2
The thread 0x2650 has exited with code 0 (0x0).
10: ClassInitializerInThread() status = _x = 2
The thread 0x1f50 has exited with code 0 (0x0).
12: ClassInitializerInThread() status = _x = 2
The thread 0x73c has exited with code 0 (0x0).
Even though the static constructor took a long time to run, the other threads stopped and waited. All threads read the value of _x set at the bottom of the static constructor.
The Common Language Infrastructure specification guarantees that "a type initializer shall run exactly once for any given type, unless explicitly called by user code." (Section 9.5.3.1.) So unless you have some whacky IL on the loose calling Singleton::.cctor directly (unlikely) your static constructor will run exactly once before the Singleton type is used, only one instance of Singleton will be created, and your Instance property is thread-safe.
Note that if Singleton's constructor accesses the Instance property (even indirectly) then the Instance property will be null. The best you can do is detect when this happens and throw an exception, by checking that instance is non-null in the property accessor. After your static constructor completes the Instance property will be non-null.
As Zoomba's answer points out you will need to make Singleton safe to access from multiple threads, or implement a locking mechanism around using the singleton instance.
Although other answers are mostly correct, there is yet another caveat with static constructors.
As per section II.10.5.3.3 Races and deadlocks of the ECMA-335 Common Language
Infrastructure
Type initialization alone shall not create a deadlock unless some code
called from a type initializer (directly or indirectly) explicitly
invokes blocking operations.
The following code results in a deadlock
using System.Threading;
class MyClass
{
static void Main() { /* Won’t run... the static constructor deadlocks */ }
static MyClass()
{
Thread thread = new Thread(arg => { });
thread.Start();
thread.Join();
}
}
Original author is Igor Ostrovsky, see his post here.
Just to be pedantic, but there is no such thing as a static constructor, but rather static type initializers, here's a small demo of cyclic static constructor dependency which illustrates this point.
Static constructor is guaranteed to be thread safe.
Also, check out the discussion on Singleton at DeveloperZen:
http://web.archive.org/web/20160404231134/http://www.developerzen.com/2007/07/15/whats-wrong-with-this-code-1-discussion/
The static constructor is locked. While the type initializer is running, any other thread which attempts to access the class in such a way that would trigger the type initializer will block.
However, the thread which is running the type initializer can access uninitialized static members. So be sure not to call Monitor.Enter() (lock(){}) or ManualResetEventSlim.Wait() from a type initializer if it is run from a UI thread—those are “interruptible” waits which result in the event loop running, executing arbitrary other parts of your program while your type initializer is still unfinished.
It is preferable for you to use managed blocking rather than unmanaged blocking. WaitHandle.WaitOne, WaitHandle.WaitAny, WaitHandle.WaitAll, Monitor.Enter, Monitor.TryEnter, Thread.Join, GC.WaitForPendingFinalizers, and so on are all responsive to Thread.Interrupt and to Thread.Abort. Also, if your thread is in a single-threaded apartment, all these managed blocking operations will correctly pump messages in your apartment while your thread is blocked: