1.单例模式简介
(1)多线程模式下,共享同一个资源或者操作同一个资源,单例模式保证一个类只生成唯一的一个对象
例如:多个线程使用同一个socket资源;配置文件的读取时。
(2)实现单例步骤常用步骤:
a) 构造函数私有化 b) 提供一个全局的静态方法(全局访问点) c) 在类中定义一个静态指针,指向本类的变量的静态变量指针2. 饿汉式单例(多线程下没问题)
不管用不用,main函数之前就已经把这个实例给创建出来了
#include <iostream> using namespace std; class Singelton { private: Singelton() //第1步:构造函数的私有化 { m_singer = NULL; m_count = 0; cout << "构造函数 Singelton ... do" << endl; } public: static Singelton *getInstance() //第2步:提供一个全局的静态方法(全局访问点) { return m_singer; } static void FreeInstance() { if (m_singer != NULL) { delete m_singer; m_singer = NULL; m_count = 0; } } private: static Singelton *m_singer; //第3步:在类中定义一个静态指针,指向本类的变量的静态变量指针 static int m_count; }; Singelton *Singelton::m_singer = new Singelton; //饿汉式单例的关键点:不管你创建不创建实例,均把实例new出来 int Singelton::m_count = 0; int main() { cout << "演示 饿汉式" << endl; Singelton *p1 = Singelton::getInstance(); Singelton *p2 = Singelton::getInstance(); if (p1 != p2) { cout << "不是同一个对象" << endl; } else { cout << "是同一个对象" << endl; //结果是同一个对象 } Singelton::FreeInstance(); Singelton::FreeInstance(); }
3. 懒汉式单例(多线程下需进行同步,本案例采用Double-Checked Locking 优化)
(1)使用的时候,才会去创建对象(2)多线程中会导致多个实例的产生,从而导致运行代码不正确以及内存的泄露。
原因: C++中构造函数并不是线程安全的,C++中的构造函数简单来说分两步: 第一步:内存分配 第二步:初始化成员变量 由于多线程的关系,可能当我们在分配内存好了以后,还没来得急初始化成员变量,就进行线程切换。 另外一个线程拿到所有权后,由于内存已经分配了,但是变量初始化还没进行,因此打印成员变量的相关值会发生不一致现象。
1 #include <iostream> 2 #include <QMutex> 3 using namespace std; 4 5 //互斥锁 6 static QMutex mutex; 7 class Singleton 8 { 9 private: 10 Singleton() //第1步:构造函数私有化 11 { 12 m_singer = NULL; 13 m_count = 0; 14 cout << "构造函数 Singelton ... do" << endl; 15 } 16 //防止拷贝构造和赋值操作 17 Singleton(const Singleton &){;}; 18 Singleton& operator = (const Singleton &){;}; 19 public: 20 static Singleton *getInstance() //第2步:提供一个全局的静态方法(全局访问点) 21 { 22 if(m_singer == NULL) //double check 23 { 24 mutex.Lock(); 25 //二次检查很重要,防止重复创建,比如第1个线程和第2线程都在mutex.Lock()等着; 26 //第一个线程创建完了,第二个线程再往下走时不判断为空就会重复创建了. 27 if(m_singer == NULL) 28 { 29 m_singer = new Singleton(); 30 } 31 mutex.Unlock(); 32 } 33 return m_singer; 34 } 35 private: 36 static Singleton *m_singer; //第3步:在类中定义一个静态指针,指向本类的变量的静态变量指针 37 static int m_count; 38 }; 39 40 Singleton *Singleton::m_singer = NULL; //懒汉式 并没有创建单例对象 41 int Singleton::m_count = 0;
标签:Singelton,变量,模式,线程,单例,多线程,构造函数 From: https://www.cnblogs.com/dkhlaojogo/p/16936572.html