C # Singleton Pattern ),
(The New handwritten blog mainly summarizes his own learning. Will explain a lot of small details .)
Singleton mode definition:
Make sure that a class has only one instance and provides a global access point.
First, we should understand that the process of generating objects by class is simple: String s = new String (), then s is an instance.
Q: How to generate only one instance?
A: 1) first, you must convert the constructor to private to prevent other classes from being instantiated. Only one constructor can be created. Because the system will default to a non-argument constructor, and the default public access modifier. Therefore, you must enter a private parameter to make the default value invalid. (The Singleton mode usually does not contain parameters)
2) declare a static instance in the class and return it through the static method.
Q: How to provide a global access point?
A: create A public and static attribute in the class. (Because the static method is a member method in the class, it belongs to the whole class, that is, it can be called directly without creating any object. In Singleton mode, other class instances are not allowed .)
Code:
There are two modes:
1. LAZY Mode
Latency loading is designed to avoid unnecessary performance overhead. The so-called latency loading is when data (read attribute values) is really needed, to load data. it can greatly improve the system performance.
2. Hunger Mode
In contrast to the LAZY mode, it will be instantiated during loading. The easiest Singleton mode.
Analysis Code 1: (Classic)
1 // do not use this method
2 public sealed class Singleton 3 {4 private static Singleton instance = null; // declare your own static instance 5 private Singleton () {} // Private construct 6 public static Singleton Instance () // provide global access point 7 {8 if (instance = null) // If the instance does not exist, create 9 {10 instance = new Singleton (); 11} 12 return instance; 13} 14}
This code is for your understanding only. The Singleton mode is defined.
Problem: This method is non-thread-safe. When two threads enter at the same time, an instance will be created if the instance is null. In fact, before the test, the instance may have been created, but the memory model cannot ensure that the instance can be seen by other threads.
Below we will optimize and improve
Code 2: (non-secure thread)
Public sealed class Singleton {private static Singleton instance = null; private static readonly object padlock = new object (); // define an identifier to ensure that the thread synchronizes Singleton () {} public static Singleton Instance () {lock (padlock) // unlock when the thread arrives after the lock is completed. When the lock thread encounters a lock, it suspends and waits for unlocking {if (instance = null) {instance = new Singleton ();} return instance ;}}}
The preceding solution solves the multithreading problem.
Problem: in terms of performance, the lock is required every time when the instance is responded. At this time, there is no need to lock the auxiliary thread object and then judge, so the above implementation method adds additional overhead.
Below we will make improvements:
Code Analysis 3: (double lock)
1 public sealed class Singleton 2 {3 private static Singleton instance = null; 4 private static readonly object padlock = new object (); 5 Singleton () {} 6 public static Singleton Instance 7 {8 get 9 {10 if (instance = null) // The outer if statement block, this makes it unnecessary for each thread to lock the instance to obtain the instance, because the lock is required only when the instance is empty (that is, an instance needs to be created) to create 11 {12 lock (padlock) 13 {14 if (instance = null) 15 {16 instance = new Singleton (); 17} 18} 19} 20 return instance; 21} 22} 23}
This "double check lock" is theoretically perfect.
The problem is: it cannot be guaranteed that it will run smoothly on a single processor or multi-processor computer. (If there is a problem, study it and see what is going on)
Code Analysis 4: (not completely LAZY)
1 public sealed class Singleton 2 {3 private static readonly Singleton instance = new Singleton (); 4 5 // The displayed static constructor 6 // The static constructor suppresses the beforefieldinit feature (the static function is executed before the access member) 7 static Singleton () {} 8 private Singleton () {} 9 public static Singleton Instance10 {11 get12 {13 return instance; 14} 15} 16}
Incomplete LAZY mode (it cannot be very effective to suppress the beforefildinit feature)
Code Analysis 5: (completely LAZY)
1 public sealed class Singleton 2 {3 private Singleton () {} 4 public static Singleton Instance {get {return Nested. instance ;}} 5 // Nested class 6 private class Nested 7 {8 // suppress beforefieldinit feature 9 static Nested () {}10 internal static readonly Singleton instance = new Singleton (); 11} 12}
Nested classes are used here (the nested types are loaded by LAZY, that is, the nested types are initialized only when they are used)
Code Analysis 6: (Lazy <T>)
1 public sealed class Singleton2 {3 // use. NET4 Lazy <T> 4 private static readonly Lazy <Singleton> lazy = new Lazy <Singleton> () => new Singleton ()); 5 public static Singleton Instance {get {return lazy. value ;}} 6 private Singleton () {} 7}
Lazy <T> object initialization is thread-safe by default. In a multi-threaded environment, the first thread that accesses the Value Attribute of the Lazy <T> object will initialize the Lazy <T> object, in the future, all accessed threads will use the data initialized for the first time.
All of the above are in LAZY mode. Now we know about the hunger mode.
Code Analysis 7:
Public sealed class Singleton {private static readonly Singleton instance = new Singleton (); // directly instantiate private Singleton () {} public static Singleton Instance () {return instance ;}}
In this mode, the CLR will solve the thread security issue for us. It can be seen that this class will be automatically instantiated when it is loaded, instead of having to create a unique singleton object after the Instance () is called for the first time.
Select the optimization mode to optimize the system. The best LAZY mode is to use Lazy <T> short security.
The above are my summary of the singleton model in the blog Park. In the future, I will add some specific project cases to make it easier for new users like me to absorb and understand the case and ultimately draw the opposite picture. I have made a special reference to this article. I hope you can give me more instructions. Thank you.