C # implementation of Singleton design mode (on)

zhaozj2021-02-16  40

Singleton design pattern C # implementation

University of Electronic Science and Technology Zhang Shen (HANDI@sina.com)

Keywords: singleton design pattern synchronous C #

1 Singleton mode.

Singleton mode is a relatively simple and common mode in the design mode.

Sometimes, in the entire application, you will ask a certain class and only one instance, this time you can use the Singleton mode. The class designed with the Singleton mode not only guarantees only one example in the application, but also provides a non-global variable for global access, called a global access point, so that the pure face to the object without global variable is a top-to-object language. Very convenient, such as C #.

This article uses a counter example to describe how to use Singleton mode in C #: The value of the count is designed as a private member variable of the counter class, which is read and written by 4 different threads, in order to ensure the correctness of the count, at the whole Application is inevitable as the instance of the counter class is unique.

2 Singleton's implementation.

First look at the two methods of the Singleton standard implementation of the textbook, the following is the class C # pseudo code:

method one:

Using system;

Namespace cspattern.singleton

{

Public Class Singleton

{

Static Singleton Unisingleton = New Singleton ();

Private kindleton () {}

Static Public Singleton Instance ()

{

Return Unisingleton;

}

}

}

Method Two:

Using system;

Namespace cspattern.singleton

{

Public Class Singleton

{

STATIC Singleton Unisingleton;

Private kindleton () {}

Static Public Singleton Instance ()

{

IF (null == unisingleton)

{

Unisingleton = new singleton _lazy ();

}

Return Unisingleton;

}

}

}

The implementation of the Singleton mode has two techniques: First, use a static member variable to save the "global" instance, ensure uniqueness, use static member method instance () instead of the new keyword to get the instance of this class, to achieve global visible effect. The second is to set the constructor into private. If you create an instance of the NEW keyword, you can compile errors to prevent the programming.

The above method II is an initialization method called Lazy Initialization. When the first time I need an instance, an instance of the class is created. The instance of the class one class is more saving system resources if the instance of the class is not used, and the method is more saving system resources. However, multiple instantiated phenomena sometimes occur in multithreaded applications.

Suppose there is 2 threads: Main threads and threads 1, when you create an instance of the class, you may encounter some reason to block a period of time (such as network speed or need to wait for some of the resource released), at this time details as following:

The main thread first calls instance () attempts to get an instance of the class, and the instance () member method determines that the class does not create a unique instance, so starting to create an instance. Due to some factors, the main thread cannot be created immediately, but you need to wait for some time. At this time, the thread 1 also calls the instance () attempt to obtain an instance of the class, because the instance has not been successfully created successfully by the main thread, so the thread 1 starts to create a new instance. The result is that the two threads have created two instances. For counter classes, the value of the count is reset, and the original intention of Singleton is contrary. The way to solve this problem is synchronization. Let's take a look at the example of the example of this article:

Method 1:

Using system;

Using system.threading;

Namespace cspattern.singleton

{

Public Class Counter

{

Static counter unicounter = new counter (); // Stores the unique instance.

Private int totnum = 0; // Stores the count value.

Private counter ()

{

Thread.sleep (100); // It is assumed to delay 100 milliseconds because of a factor.

// Do not affect the count in the case of non-Lazy Initialization. .

}

Static Public Counter Instance ()

{

Return Unicounter;

}

Public void inc () {TOTNUM ;} / / count plus 1.

Public int getCounter () {return totnum;} // Get the current count value.

}

}

The following is a client called the Counter class, where we define four threads simultaneously using a counter, 4 times for each thread, and finally the correct result should be 16:

Using system;

Using system.io;

Using system.threading;

Namespace cspattern.singleton.mutilethread

{

Public Class MutileClient

{

Public mutileclient () {}

Public void dosomework ()

{

Counter mycounter = counter.instance (); // method one

// counter_lazy mycounter = counter_lazy.instance (); // method two

For (int i = 1; i <5; i )

{

mycounter.inc ();

Console.writeline ("Thread {0} Report: Current counter: {1}", thread.currentthread.name.tostring (), mycounter.getCounter (). Tostring ());

}

}

Public void clientmain ()

{

Thread thread0 = thread.currentthread;

Thread0.name = "thread 0";

Thread thread1 = new thread (New ThreadStart (this.dosomework);

Thread1.name = "thread 1";

Thread thread2 = new thread (New ThreadStart (this.dosomework);

Thread2.name = "thread 2";

Thread thread3 = new thread (new threadstart (this.dosomework)); thread3.name = "thread 3";

Thread1.start ();

Thread2.start ();

Thread3.start ();

DOSMEWORK (); // thread 0 also only performs the same work as other threads.

}

}

}

(Next half)

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

New Post(0)