什么是单例模式
单例模式:是一种常用的软件设计模式。在它的核心结构中只包含一个被称为单例的特殊类。通过单例模式可以保证系统中一个类只有一个实例。即一个类只有一个对象实例。
单例类的实现
构造函数声明为私有(private)或者保护类型(protected),内部定义一个private的static的类类型指针,保存唯一的对象实例,通过一个public的initance方法实例化对象。
class singleton
{
protected:
singleton(){}
private:
static singleton* pSig;
public:
static singleton* instance();
};
singleton* singleton::pSig = NULL;
singleton* singleton::instance()
{
if (pSig == NULL)
pSig = new singleton();
return pSig;
}
注意:往往并没有这么简单,我们需要考虑线程安全,假如两个线程同时检测到内部的指针pSig为空同时创建了实例,那么这样就不符合单例模式的定义了,同时这也是不安全的,错误的。
- 懒汉与饿汉
单例模式有两种实现方法懒汉与饿汉。
懒汉:只有在第一次用到类实例时才会实例化。
饿汉:饿了就饥不择食,在单例类定义的时候就应该实例化。
优缺点比较
在线程比较多或者访问量比较大时,由于需要线程同步采用饿汉实现,以空间换时间。
在访问量比较小时采用懒汉实现,以时间换空间。
- 线程安全的懒汉实现
1.加锁的懒汉实现。
class singleton
{
protected:
singleton()
{
pthread_mutex_init(&mutex,NULL);
}
private:
static singleton *pSig;
public:
static pthread_mutex_t mutex;
static singleton *initance();
int i;
};
pthread_mutex_t singleton::mutex;
singleton *singleton::pSig = NULL;
singleton *singleton::initance()
{
if(NULL == pSig)
{
pthread_mutex_lock(&mutex);
if(NULL == pSig)
pSig = new singleton;
pthread_mutex_unlock(&mutex);
}
return pSig;
}
2.内部静态变量的内部实现
class singleton
{
protected:
singleton()
{
pthread_mutex_init(&mutex,NULL);
}
public:
static pthread_mutex_t mutex;
static singleton *initance();
int i;
};
pthread_mutex_t singleton::mutex;
singleton *singleton::initance()
{
pthread_mutex_lock(&mutex);
static singleton obj;
pthread_mutex_unlock(&mutex);
return &obj;
}
- 饿汉实现
class singleton
{
protected:
singleton()
{}
private:
static singleton *pSig;
public:
static singleton *initance();
int i;
};
singleton *singleton::pSig = new singleton;
singleton *singleton::initance()
{
return pSig;
}
饿汉本身就是线程安全的。