Yesterday I published an article "about the dual-check locking Singleton mode", demonstrating that DCL is not feasible in Java, for an extremely high reason.
Finally, I mentioned that C # cannot use DCL.
Then many of my friends pointed out that C # supports DCL. Later, I did see in a document that using DCL above. net2.0 is secure. Here we will first revise my previous statement.
However, this means that DCL does not work well in all C # versions. However, there is a mode that can achieve the DCl delay loading goal without any synchronization, And it is thread-safe.
The key to this mode is to use the class loading mechanism of the JVM/CLR runtime. Let's take a look at the code
Java:
1 public class Singleton {
2
3 private Singleton (){}
4
5 Private Static class nested {
6 static Singleton instance = new Singleton ();
7}
8
9 public static Singleton getinstance (){
10 return nested. instance;
11}
12}
C #:
1 public class Singleton {
2
3 private Singleton (){}
4
5 Private Static class nested {
6 // original wrong code:
7 // static Singleton instance = new Singleton ();
8 // fixed:
9 internal static Singleton instance = new Singleton ();
10}
11
12 public static Singleton getinstance (){
13 return nested. instance;
14}
15}
16
The two codes are exactly the same.
In this mode, a static internal class is defined within the singleton class, and an instance of its own is held by the internal class.
This is because for the JVM/CLR runtime, class information, including class variables, is loaded only when this class is used for the first time, that is, "load on demand ".
Before calling the getinstance () method, the nested internal class is never used, so the class variables are not initialized at all. When the getinstance () method is called for the first time, because the interpreter encounters a nested class that has never been seen, it tries to load and initialize all static variables in the class, in this way, the instance variable is delayed.
In addition, why use an internal class instead of defining a new instanceholder class? Because internal classes have two major characteristics that cannot be replaced by other classes.
-It can be private. Except for Singleton, no other code can access the nested class.
-It can access private variables and methods of external classes. As shown in the previous code, the nested class can still call the private constructor of the external class.
Although this mode does not have synchronization blocks, there is no need to worry about thread security. It depends on the processing of class loading during the runtime, the runtime ensures the visibility and atomicity of class initialization for any thread.