单例模式:一个类只能生成一个对象
快加载的单例模式:
1、私有化构造函数
2、提供对象实例的接口
3、创建私有化的单例对象
快加载的单例模式:
class Singleton
{
public:
static Singleton* getInstance()//2.该公有接口专门返回对象实例
{
return &sobj;
}
private:
Singleton();//1.私有化构造函数
{
;
}
static Singleton sobj;
};
Singleton Singleton::sobj;//3.创建单例对象
快加载是因为该对象跟随程序的开始就初始化在数据段中
慢加载的单例模式:和快加载的原理相似,但是这个时候是把初始化过程放到了函数的调用过程开始初始化。
实现慢加载的单例模式,考虑线程安全
写法一:使用静态变量只初始化一次的特点
class Singleton
{
public:
static Singleton* getInstance()//2.该公有接口专门返回对象实例
{
pthread_mutex_lock(&mutex);
static Singleton sobj;//初始化单例对象
//静态局部变量的初始化是由编译器保证它的原子操作的 gcc4.6版本以上
//4.6以下版本需要自己加锁保证初始化的线程安全
pthread_mutex_unlock(&mutex);
return &sobj;
}
~Singleton()
{
pthread_mutex_destroy(&mutex);
}
private:
Singleton();//1.私有化构造函数
{
;
}
static pthread_mutex_t mutex;
};
pthread_mutex_t Singleton::mutex = PTHREAD_MUTEX_INITIALIZER;
写法二:使用new人为控制
class Singleton
{
public:
static Singleton* getIntance()
{
pthread_mutex_lock(&mutex);//多线程线程安全问题
if (pobject == NULL)//懒加载,只有在使用时才生成
{
pobject = new Singleton();
}
pthread_mutex_lock(&mutex);
return pobject;
}
private:
Singleton(){}//1.私有化构造函数
{
;
}
static Singleton *pobject;
};
Singleton* Singleton::pobject = NULL;//快加载 懒加载
实现线程安全的懒加载单例模式
class Base
{
private:
Base(){}
};
class Singleton// : public Base需要实现多个不同的单例模式时
//不需要对每个类的构造函数都私有化,直接从基类中继承过来
{
public:
static Singleton* getInstance()//2.该公有接口专门返回对象实例
{
if(sobj == NULL)
{
pthread_mutex_lock(&mutex);
if(sobj == NULL)
sobj = new Singleton();
//锁的双重判断实现线程安全的懒加载单例模式
//不仅保证安全也提高效率(缩小锁的临界区代码)
pthread_mutex_unlock(&mutex);
//锁的释放过程做两件事情
//1.会把线程缓存的值刷新到原始内存当中
//2.其他线程可以获取这把锁了
}
return sobj;
}
~Singleton()
{
pthread_mutex_destroy(&mutex);
}
private:
Singleton();//1.私有化构造函数
{
;
}
static Singleton *volatile sobj;
//对于线程加共享变量的使用volatile保证安全性 //1.volatile关键字阻止编译器为了提高速度将一个变量缓存到寄存器内而不写回内存
//2.volatile关键字阻止编译器调整操作volatile变量的指令操作
static pthread_mutex_t mutex;
};
Singleton *volatile Singleton::sobj = NULL;
pthread_mutex_t Singleton::mutex = PTHREAD_MUTEX_INITIALIZER;