1 /// <summary>2 ///double check Lock implementation single case3 /// </summary>4 Public Sealed classSingletondoublecheck5 {6 //The S_lock object is required for thread safety, and when defining this object, we assume that the cost of creating a singleton object is higher than creating a System.Object object7 //and assume that you might not need to create a singleton object at all, it would be more economical and easier to create a singleton object in a class builder8 Private StaticObject S_lock =NewObject ();9 Ten //This field refers to a singleton object One Private StaticSingletondoublecheck S_value =NULL; A - //The private constructor blocks any code outside this class from creating an instance - PrivateSingletondoublecheck () the { - - } - + //the following public static method returns a singleton object (creating it if necessary) - Public StaticSingletondoublecheck Getsingleton () + { A //If the Singleton object is already created, return it directly at if(S_value! =NULL) - { - returnS_value; - } - - //acquires an exclusive lock on the specified object in Monitor.Enter (s_lock); - to //Check again to see if you have created + //Workaround: If multiple threads are entered at the first time (the Singleton object has not yet been created), then only one thread executes the following code (because there is a monitor), - //when the thread (the first thread) finishes creating an instance, another thread (the second thread) immediately obtains the lock, and executes the following code, the //Now that the instance has been created, the subsequent thread should return directly to it, so you can determine if the instance has been created. * if(S_value = =NULL) $ {Panax Notoginseng //create it if it is still not created -Singletondoublecheck Singleton =NewSingletondoublecheck (); the + //give the singleton to S_value . A //The following code guarantees that references in Singleton are published to S_value only after the constructor finishes execution theVolatile.write (refS_value, singleton); + - //Note: The following wording is not reliable $ //because the compiler might do this: $ //1. Allocating memory for Singletondoublecheck - //2. Publish the reference to (assign) S_value - //3. Calling the constructor the //Suppose that after a reference is published to S_value, but before the constructor is called, if another thread calls Getsingleton, - //at this point, s_value is not NULL, and the thread uses the object, but the constructor for the object has not yet finished executing. Wuyi //s_value = new Singletondoublecheck (); the } - Wu //frees an exclusive lock on the specified object - Monitor.Exit (s_lock); About $ returnS_value; - } - } - A /// <summary> + ///simple construction of a single case method under C # the ///The CLR has ensured that the construction of the class is thread-safe and that writing is simple - ///The disadvantage is also obvious that the type constructor will be called when any member of the class is first accessed $ ///Therefore, if the class defines other static members, the object is created when any other static member is accessed the /// </summary> the Public Sealed classSingletonsimple the { the Private StaticSingletonsimple S_value =Newsingletonsimple (); - in //The private constructor blocks any code outside this class from creating an instance the Privatesingletonsimple () the { About the } the the //the following public static method returns a singleton object (creating it if necessary) + Public Staticsingletonsimple Getsingleton () - { the returnS_value;Bayi } the the //or - Public Staticsingletonsimple singletoninstance - { the Get{returnS_value;} the } the the //or - Public StaticSingletonsimple Instance {Get; } =Newsingletonsimple (); the } the the /// <summary>94 ///nested classes implementing a singleton the ///multiple singletonnested objects may be created if multiple threads call Getsingleton at the same time the ///However, due to the use of interlocked.compareexchange, it is guaranteed that only one reference will be published to S_value the ///objects that are not pinned will be garbage collected98 ///this way does not block the thread About /// </summary> - Public Sealed classsingletonnested101 {102 Private Staticsingletonnested S_value =NULL;103 104 //The private constructor blocks any code outside this class from creating an instance the Privatesingletonnested ()106 {107 108 }109 the //the following public static method returns a singleton object (creating it if necessary)111 Public Staticsingletonnested Getsingleton () the {113 //If the Singleton object is already created, return it directly the if(S_value! =NULL) the { the returnS_value;117 }118 119 //Create a new singleton object and pin it down (if another thread hasn't fixed it yet) -singletonnested singletonnested =Newsingletonnested ();121 122 //compares an instance of two specified reference types if T is equal, replaces the first if equal, and returns the S_value original value123 //S_value is compared with NULL, if equality is replaced with singletonnested s_value, otherwise it is not replaced124Interlocked.compareexchange (refS_value, singletonnested,NULL); the 126 //if the thread fails to compete, the newly created second single-instance object is garbage collected127 - returnS_value;129 } the}
Three ways to build a C # singleton pattern