Singleton mode :

  Singleton pattern is a common software design pattern , Its core structure contains only one special class called singleton . The singleton pattern can ensure that there is only one instance of a class in the system, and the instance is easy to access , So it is convenient to control the number of instances and save system resources . If you want only one object of a class to exist in the system , Singleton mode is the best solution .

Requirements of singleton mode :

* Privatization of constructors
* Add static private class pointer variable
* Add static public interface , It allows users to obtain singleton objects
Basic form of singleton pattern :
class A { private: A(){ a=new A; } public: static A* getInstance(){ return a;
} private: static A* a; } // call A* A::a=NULL;
Classification of singleton patterns :

Sluggard style : Create the instantiation of the class directly .

            Space for time , Because it instantiates an object , Occupied memory , And whether or not the main program uses this class .

Hungry man style : Create instantiations of classes when needed .

            Time for space , It's the opposite of starvation .

Lazy code example :
/* Lazy singleton model */ class Singleton_lazy{ private: /* Privatization of constructors , Ensure that it is not instantiated outside the class */
Singleton_lazy(){cout<<" I'm a slacker "<<endl;} public: /* User interface , Create an instance of a class when using it */
static Singleton_lazy* getInstance(){ // judge pSingleton Is it NULL, If NULL, That is to say, it needs to be instantiated if
(pSingleton==NULL){ pSingleton=new Singleton_lazy; } return pSingleton; }
private: static Singleton_lazy* pSingleton; // Static class object }; // Static object out of class initialization
Singleton_lazy* Singleton_lazy::pSingleton=NULL;
Chinese code example :
/* Starving Chinese single instance mode */ class Singleton_hungry{ private:
Singleton_hungry(){cout<<" I'm a hungry man "<<endl;} public: /* Returns the created class instance */ static
Singleton_hungry* getInstance(){ return pSingleton; } private: static
Singleton_hungry* pSingleton; }; // Out of class initialization : Create an instance of the class directly Singleton_hungry*
Singleton_hungry::pSingleton=new Singleton_hungry;
Comparative test :

In the above lazy style , On the basis of starving Chinese type singleton class, test and compare :

* In the main function , Only lazy singleton class objects are created , However, in the result of code running, it is obvious that there is the result of constructor calling of starved singleton class , explain
Lazy needs to be instantiated actively outside the class , The hungry type is instantiated automatically after the class is defined .
* According to the result of the code running , The starving singleton class is executing main Function has been instantiated before calling the constructor , And the lazy singleton class is in the main Function internal active instantiation calls the constructor .
int main() { cout<<"main Function start "<<endl; Singleton_lazy*
p1=Singleton_lazy::getInstance(); return 0; } /* Test code output results */ I'm a hungry man main Function start
I'm a slacker
Comparison and selection :

* Due to the need for thread synchronization , So there are a lot of visits , Or there may be more threads visited , Using hungry man to realize , Can achieve better performance . It's space for time .
* When the traffic is small , Using lazy people to achieve . It's time for space .
Singleton mode and multithreading

Lazy encounter multithreading , It's not thread safe . resolvent : Lock .

Starved man encounters multithreading , It's thread safe . Because the class instance object has been created before multithreading , It will not be re instantiated , It's thread safe .

Lazy singleton class with thread safety :
/* Lazy singleton class with thread safety */ class Singleton_lazy{ protected: Singleton_lazy() {
pthread_mutex_init(&mutex,NULL); } public: static Singleton_lazy*
getInstance(); static pthread_mutex_t mutex; private: static Singleton_lazy*
pSingleton; }; pthread_mutex_t Singleton_lazy::mutex; Singleton_lazy*
Singleton_lazy::pSingleton=NULL; Singleton_lazy*Singleton_lazy::getInstance() {
if (pSingleton==NULL) { pthread_mutex_lock(&mutex); if(pSingleton==NULL)
pSingleton=new Singleton_lazy; pthread_mutex_unlock(&mutex); } return
pSingleton; }