Does static initialization guarantee the safety of single-threaded threads? (FROM#)

Possible duplicate:
Is C # static constructor thread safe?

John Skeet's good article at http://csharpindepth.com/Articles/General/Singleton.aspx and the other articles I read make it clear that this double-check lock does not work in both C # and Java if only explicitly does not put the instance as "volatile". If you do not, checking a comparison with a null value may return false, even if the instance constructor has not finished working. In Mr. Skeet’s third example, he clearly states: β€œThe Java memory model does not guarantee that the constructor will exit before the reference to the new object is assigned to the instance. The Java memory model has been reworked for version 1.5, but the double-even lock still interrupted after that without the volatile variable (as in C #) "

However, most agree (including Mr. Skeet, in examples 4 and 5 in his article), that using static initialization is an easy way to get a streaming single-user instance. He claims that "static constructors in C # are set to execute only when instantiating a class or mentioning a static member and to execute only once for AppDomain."

This makes sense, but what seems to be missing is a guarantee that a link to a new object will only be assigned after the constructor completes - otherwise we will get the same problem that makes a double-check lock if you do not check the instance how volatile. Is there a guarantee that when using static initialization to call the instance constructor (as opposed to calling the instance constructor from the get {} property, as well as when locking with double check), the constructor will be completely filled before any other thread can get a reference to the object?

Thanks!

+7
multithreading constructor c # singleton
source share
2 answers

that the constructor will be completely populated before any other thread can get an object reference?

A static initializer will only be called once (at least by the system) behind the AppDomain and in a synchronized manner, taking into account the "beforefieldinit". Therefore, assuming that you are not doing anything fancy, any static fields assigned in the static initializer should be fine; any other attempts to use the static field should be held (blocked) by the static constructor.

a reference to a new object is assigned only after the constructor completes

It happens when it happens. All static field initializers occur before what you usually consider a constructor, for example. But since other threads are blocked, this should not be a problem.

But:

  • if your static initializer itself passes the link from the outside (by calling the method with the link as an argument (including "arg0"), then all bets are disabled
  • If you use reflection to call a static constructor (yes, you can do it), madness often follows
+9
source share

Yes; The guarantee is that it will be executed only once for AppDomain.

This may be unsafe if it can be executed more than once; as said, he cannot, so everything is fine :)

+2
source share

All Articles