one, multi-threaded insecure way to achieve
public sealed class SingleInstance { private static singleinstance instance; Private SingleInstance () {} public static singleinstance Instance { get { if (null = = Instance) { instance = new SingleInstance (); } return instance;}} }
Sealed indicates that singleinstance cannot be inherited. In fact, the privatization of the constructor has achieved this effect, and private constructors cannot be inherited. For readability, you can add a sealed.
Unsafe Singleton refers to the possibility of multiple threads entering an if statement in a multithreaded environment, creating multiple singleton objects.
Ii. Safe Single-case mode
public sealed class SingleInstance { private static volatile singleinstance instance; private static readonly Object obj = new Object (); Private SingleInstance () {} public static singleinstance Instance { get { if (null = = Instance) c10/>{ Lock (obj) { if (null = = instance) { instance = new SingleInstance ();} } } return instance;}} }
Lock protection, which ensures that instance values are created once in multiple threads. The disadvantage is that each time the acquisition of a single case, to be judged, involving the lock and unlock compared to resource consumption.
Third, read-only attribute
public sealed class SingleInstance { private static readonly singleinstance instance = new SingleInstance (); Private SingleInstance () {} public static singleinstance Instance { get { return Instance; } } }
With the ReadOnly attribute, the instance is initialized only once, which also achieves the effect of a singleton. Before the main function executes the first sentence, the instance is actually assigned, and it is not expected that the object will be created until the instance variable is accessed.
The following code:
Class program { static void Main (string[] args) { Console.WriteLine ("Begin"); var temp = singleinstance.instance;; } } public sealed class SingleInstance {public static readonly singleinstance instance = new SingleInstance (); Private SingleInstance () { Console.WriteLine ("Init initialization! "); } public static singleinstance Instance { get {return Instance;} }
Output:
The instance has already been initialized before executing the first sentence of code.
The workaround is to add a static constructor to the singleinstance.
public sealed class SingleInstance {public static readonly singleinstance instance = new SingleInstance (); Static singleinstance () {} Private singleinstance () { Console.WriteLine ("Initialize initialization! "); } public static singleinstance Instance { get {return Instance;} }
In the run output:
Iv. Use of lazy
public sealed class SingleInstance { private static readonly lazy<singleinstance> instance = new Lazy <SingleInstance> (() = new singleinstance ()); Private SingleInstance () {} public static singleinstance Instance { get { return Instance. Value;}} }
Lazy is thread-safe by default. MSDN describes the following:
Would the lazily initialized object be accessed from more than one thread?If So, theLazy<t> object might create it on any thread.You can use one of the constructors whose default behavior are to create a Thread-safe lazy <t > object, so that is only one instance of the lazily Instantiated object is created no matter what many threads try to access It. lazy < T > object, you must use a constructor that does not allow you to specify thread security. ">to create a lazy <t > object That's not the thread safe, you must Use a constructor This enables you to specify no thread safety.
V. Generic single-CASE
Class Program {static void Main (string[] args) {Console.WriteLine ("Begin"); MySingle.Instance.age = 500; Console.WriteLine (MySingle.Instance.age); }} public abstract class Singleinstance<t> {private static readonly lazy<t> _instance = new Lazy<t> (() = {var ctors = typeof (T). GetConstructors (bindingflags.instance| bindingflags.nonpublic| BindingFlags.Public); if (ctors. Count ()! = 1) throw new InvalidOperationException (String.Format ("Type {0} must has exactly one Constru ctor. ", typeof (T))); var ctor = ctors. Singleordefault (c = c.getparameters (). Count () = = 0 && c.isprivate); if (ctor = = null) throw new InvalidOperationException (String.Format ("the constructor for {0} must is PR Ivate and take no parameters. ", typeof (T))); Return (T) ctor. Invoke (NULL); }); public static T Instance {get{return _instance. Value;} }} public class Mysingle:singleinstance<mysingle> {private Mysingle () {} "public int" age; }
C # Singleton mode