单例模式:只有一个类实例化对象
1. 私有构造
2.定义该类型的唯一对象
3. 使用静态方法返回一个对象
饿汉单例模式
//无论用不用到该对象,都会在使用之前就直接创建唯一对象
//在类开始被加载后,就会创建对象,因此它是一个线程安全的
class Singleton
{
public:
static Singleton *getInstance()
{
return instance;
}
private:
Singleton() { cout << "Singleton()" << endl; }
Singleton(const Singleton &instance) { cout << "Singleton(const Singleton &)" << endl; }
static Singleton *instance;
};
Singleton* Singleton::instance = new Singleton();
int main()
{
Singleton *p1 = Singleton::getInstance();
Singleton *p2 = Singleton::getInstance();
Singleton *p3 = Singleton::getInstance();
cout << p1 << " " << p2 << " " << p3 << endl;
return 0;
}
非线程安全的懒汉单例模式
class Singleton
{
public:
static Singleton *getInstance()
{
if (instance == nullptr)
{
instance = new Singleton();
}
return instance;
}
private:
static Singleton *instance;
Singleton() { cout << "Singleton()" << endl; }
Singleton(const Singleton &instance) { cout << "Singleton(const Singleton &)" << endl; }
~Singleton() { cout << "~Singleton()" << endl; }
class Release
{
public:
~Release()
{
if (instance != nullptr)
{
delete instance;
instance = nullptr;
}
}
};
static Release del;
};
Singleton *Singleton::instance = nullptr;
Singleton::Release Singleton::del;
int main()
{
Singleton *p1 = Singleton::getInstance();
Singleton *p2 = Singleton::getInstance();
cout << p1 << " " << p2 << endl;
return 0;
}
线程安全的单例模式
//频繁的加锁解锁 效率低下
class Singleton
{
public:
static Singleton *getInstance()
{
pthread_mutex_lock(&_mutex);
if (instance == nullptr)
{
instance = new Singleton();
}
pthread_mutex_unlock(&_mutex);
return instance;
}
private:
Singleton()
{
cout << "Singleton()" << endl;
}
Singleton(const Singleton &instance)
{
cout << "Singleton(const Singleton&)" << endl;
}
~Singleton()
{
pthread_mutex_destroy(&_mutex);
cout << "~Singleton()" << endl;
}
class Release
{
public:
~Release()
{
if (instance != nullptr)
{
delete instance;
instance = nullptr;
}
}
};
static Release rel;
static Singleton *instance;
static pthread_mutex_t _mutex;
};
Singleton *Singleton::instance = nullptr;
pthread_mutex_t Singleton::_mutex = PTHREAD_MUTEX_INITIALIZER;
Singleton::Release Singleton::rel;
int main()
{
Singleton *p1 = Singleton::getInstance();
Singleton *p2 = Singleton::getInstance();
cout << p1 << " " << p2 << endl;
return 0;
}
线程安全的单例模式
//锁+双重判断 减少加锁解锁
class Singleton
{
public:
static Singleton *getInstance()
{
if (instance == nullptr)
{
pthread_mutex_lock(&_mutex);
/*
问题:在外面已经进行一次instance判空 为什么加锁后还要进行判空
此时需要在进行一次判空
原因:有多个线程在第一次判断空时进入了第一个if语句
此时如果不在进行判空 在解锁后会有线程再次去进行new对象
*/
if (instance == nullptr)
{
instance = new Singleton();
}
pthread_mutex_unlock(&_mutex);
}
return instance;
}
private:
Singleton()
{
cout << "Singleton()" << endl;
}
Singleton(const Singleton &instance)
{
cout << "Singleton(const Singleton&)" << endl;
}
~Singleton()
{
pthread_mutex_destroy(&_mutex);
cout << "~Singleton()" << endl;
}
class Release
{
public:
~Release()
{
if (instance != nullptr)
{
delete instance;
instance = nullptr;
}
}
};
static Release rel;
static Singleton *instance;
static pthread_mutex_t _mutex;
};
Singleton *Singleton::instance = nullptr;
pthread_mutex_t Singleton::_mutex = PTHREAD_MUTEX_INITIALIZER;
Singleton::Release Singleton::rel;
int main()
{
Singleton *p1 = Singleton::getInstance();
Singleton *p2 = Singleton::getInstance();
cout << p1 << " " << p2 << endl;
return 0;
}
划重点!!!
单例模式的类模板
无论类型怎么变,都可以用这个类模板
/************************************************************************
singleton模式类模板
1:延迟创建类实例 2:double check 3:互斥访问 4:模板
************************************************************************/
template<class T>
class CSingleton
{
private:
static T* _instance;
CSingleton(void);
static CThreadLockCs lcs;
public:
static T* Instance(void);
static void Close(void);
};
//模板类static变量
template<class T>
T* CSingleton<T>::_instance = NULL;
//模板类方法实现
template<class T>
CSingleton<T>::CSingleton(void)
{
}
template<class T>
T* CSingleton<T>::Instance(void)
{
//double-check
//延迟创建,只有调用方访问Instance才会创建类实例
if (_instance == NULL)
{
//互斥访问锁,用CriticalSection实现
lcs.lock();
if (_instance == NULL)
{
_instance = new T;
}
lcs.unlock();
}
return _instance;
}
template<class T>
void CSingleton<T>::Close(void)
{
if (_instance)
{
delete _instance;
}
}