C # implement Singleton

zhaozj2021-02-16  85

You have to build an application in C #. You need to have only one instance class and need to provide a global access point for accessing instances. You want to make sure your solution is efficient and can use Microsoft® .NET Public Language Running Function. You may also want to make sure the solution is threaded.

Implementation strategy

Although Singleton is a relatively simple mode, there are different trade-off factors and options associated with specific implementation. Below is a set of implementation strategies, and its advantages and disadvantages.

Singleton

The following implementation of the Singleton Design Mode The solution described in Design Patterns: Elements of Reusable Object-Oriented Software [gamma95] is modified to use the language functions available in C #, such as attributes:

using System; public class Singleton {private static Singleton instance; private Singleton () {} public static Singleton Instance {get {if (instance == null) {instance = new Singleton ();} return instance;}}}

There are two main points of this implementation:

Since the example is created inside the instance property method, the class can use additional features (for example, instantiate the subclass), even if it may introduce unwanted dependence. Until the object requires an instance to perform instances; this method is called "lazy instantiation". Lazy instantification avoids unnecessary Singleton when the application is started.

However, the main disadvantage of this implementation is that it is unsafe in a multi-threaded environment. If the different threads of the execution process are simultaneously entered into the instance property method, multiple Singleton object instances may be created. Each thread performs the following statements and decides to create a new instance:

IF (instance == null)

There are many ways to solve this problem. One method is to use techniques called Double-Check Locking [Lea99]. The C # and the public language running library also provides a "static initialization" method, which does not require developers to explicitly write thread security codes to solve these problems.

Static initialization

One of the Reasons Design Patterns [gamma95] Avoid using a reason for static initialization, and the C specification has left some polyses in the initialization order of static variables. Fortunately, .NET Framework solves this polymity through its variable initialization processing method:

Public Sealed Class Singleton {Private Static Readonly Singleton Instance = New Singleton (); Private Singleton () {} PUBLIC SINGLETON Instance;}}}

In this policy, an instance will be created when any member of the first reference class. The public language runtime is responsible for processing variable initialization. This class is marked as Sealed to prevent derivation of derivation, and derived may increase the instance. For discussion of interest and disadvantages marked as Sealed, see [Sells03]. In addition, the variable is marked as readonly, which means that the variable can only be allocated during static initialization (exemplified here) or in the class constructor.

This implementation is similar to the previous example, which is different in that it rely on the public language runtime to initialize the variable. It can still be used to solve two basic problems that SINGLETON mode attempts to solve: global access and instantiation control. Public static properties provide a global access point for access instances. In addition, since the constructor is private, the Singleton class cannot be instantiated outside the class itself; therefore, the variable reference is the only instance that can be present in the system. Since the Singleton instance is referenced by private static member variables, it will not be instantiated before the class is first referenced to the invocation of the instance property. Therefore, like Singleton in the form of Design Patterns, the solution implements a form of lazy realization properties.

The only potential disadvantage of this method is that you have less control over the instantiation mechanism. In Design Patterns, you can use non-default constructor or perform other tasks before instantiation. Since the .NET Framework is initialized by the .NET Framework in this solution, you don't have these options. In most cases, static initialization is the preferred method of implementing Singleton in .NET.

Multithreaded Singleton

Static initialization is suitable for most situations. If your application must be delayed, use non-default constructor before instantiation or other tasks, and work in a multi-threaded environment, you need another solution. However, in some cases, you cannot reluctance to ensure the security of the thread like the public language running library as in the Static Initialization example. In this case, a specific language function must be used to ensure only one object instance is created in the presence of a multi-thread. One of the more common solutions is to use Double-Check Locking [Lea99] technology to block different threads simultaneously create new instances of Singleton.

Note: The public language runtime resolves commonly commonly common in other environments and is related to the Double-Check Locking. For more information on these issues, please refer to the "The 'Double-Checked Locking Is Broken' Declaration" in the University of Maryland, the URL is http://www.cs.umd.edu/~pugh/java/MemoryModel /Doucastlocking.html.

The following implementation only allows a thread to enter a critical area in the case where a Singleton instance is not created (the area is identified by the LOCK block).

using System; public sealed class Singleton {private static volatile Singleton instance; private static object syncRoot = new Object (); private Singleton () {} public static Singleton Instance {get {if (instance == null) {lock (syncRoot) { IF (instance == null) instance = new singleleton ();}} Return Instance;}}}

This method ensures that only one instance is created only when an instance is needed. In addition, variables are declared as Volatile to ensure that instance variables can only be accessed only after the instance variable assignment is completed. Finally, this method uses the syncroot instance to lock (not the lock type itself) to avoid deadlocks.

This Double-Check Locking method solves the thread concurrency problems while avoiding exclusive locks in the calls of each instance property method. It also allows you to instantiate delay when you first access objects. In fact, the application rarely requires this type of implementation. In most cases, the static initialization method is already enough. Result context

Implementing Singleton in C # has the following excellent disadvantages:

advantage

Since the .NET Framework explicitly specifies how the static variable initialization and when it occurs, the static initialization method is possible. The Double-Check Locking technology described in the previous "Multithreaded Singleton" has been properly implemented in the public language runtime.

Disadvantage

If your multi-threaded application needs to explicitly initialize, you must take action to avoid thread problems.

转载请注明原文地址:https://www.9cbs.com/read-13904.html

New Post(0)