Well-known double check technology in C #

I saw this singleton recommendation (with partial code) in the mprss book:

public static Singleton GetSingleton() { if (s_value != null) return s_value; Monitor.Enter(s_lock); if (s_value == null) { Singleton temp = new Singleton(); Interlocked.Exchange(ref s_value, temp); } Monitor.Exit(s_lock); return s_value; } 

We add two lines of code in the second block of the if statement, and not just write:

 s_value = new Singleton(); 

this should handle the situation when the second thread enters the method and finds s_value != null but not initialized.


My question is: can we just write on the second if block:

 { Singleton temp = new Singleton(); s_value = temp; // instead of Interlocked.Exchange(ref s_value, temp); } 

So now the function:

 public static Singleton GetSingleton() { if (s_value != null) return s_value; Monitor.Enter(s_lock); if (s_value == null) { Singleton temp = new Singleton(); s_value = temp; } Monitor.Exit(s_lock); return s_value; } 

I think not, because they do not use it.

Does anyone have any suggestions?


Is it possible that an svalue might contain uninitialized ones? The svalue can be built right after temp has been fully initialized (maybe I'm wrong). if I'm wrong, maybe an example point, is that wrong? can the compiler generate other code?


+6
source share
2 answers

I will post this not as a real answer, but as an aside: if you are using .NET 4, you really should consider the Lazy<T> singleton template:

http://geekswithblogs.net/BlackRabbitCoder/archive/2010/05/19/c-system.lazylttgt-and-the-singleton-design-pattern.aspx

 public class LazySingleton3 { // static holder for instance, need to use lambda to construct since constructor private private static readonly Lazy<LazySingleton3> _instance = new Lazy<LazySingleton3>(() => new LazySingleton3()); // private to prevent direct instantiation. private LazySingleton3() { } // accessor for instance public static LazySingleton3 Instance { get { return _instance.Value; } } 

}

Thread safe, easy to read, and obvious: what's not to like?

+7
source

While the assignment is atomic, it also requires that the memory be “synchronized” across different cores / CPUs (full fence), or another core that reads the value at the same time can get an obsolete value (outside the synchronization block), the Interlocked class does this for all their operations.

http://www.albahari.com/threading/part4.aspx

Edit: Wikipedia has useful information about problems with the double lock pattern and where / when to use memory barriers to work.

+4
source

Source: https://habr.com/ru/post/904665/


All Articles