文章目录
- 1.单例模式的特点😊
- 2.单例模式两种实现🤣🤗😊
-
- [2.1 饿汉式](#2.1 饿汉式)
- [2.2 懒汉式](#2.2 懒汉式)
- 3.传统单例模式的线程安全问题
- 4.解决方法
1.单例模式的特点😊
1.全局只有一个类的static实例存在;
2.不允许直接实例化,构造函数为私有的,只通过一个类的静态方法获取该实例;
2.单例模式两种实现🤣🤗😊
2.1 饿汉式
饿汉式是在类加载的时候就会创造实例,会造成资源的浪费。 具体:内部先定义并初始化好了一个静态实例。获取方法中直接返回实例。
特点:线程安全,会造成资源浪费
实现:
cpp
class Singleton {
private:
static Singleton instance;
// 私有构造函数,防止类外实例化对象
Singleton() {}
public:
// 获取实例的静态方法
static Singleton& getInstance() {
return instance;
}
// 其他成员函数
void doSomething() {
// do something
}
};
// 静态成员变量需要在类外初始化
Singleton Singleton::instance;
int main() {
// 获取单例对象实例
Singleton& singleton = Singleton::getInstance();
// 调用单例对象的方法
singleton.doSomething();
return 0;
}
2.2 懒汉式
懒汉式是在需要时才创建实例,通过获取实例方法获取实例。
具体:内部定义一个静态实例,获取方法中判断实例是否为空,空则初始化实例;否则返回该实例
特点:避免资源浪费,造成线程安全问题。
实现
cpp
class Singleton {
private:
// 静态成员变量,用于保存单例实例
static Singleton* instance;
// 构造函数私有化,防止外部创建实例
Singleton() {}
public:
// 静态成员函数,用于获取单例实例
static Singleton* getInstance() {
// 判断实例是否为空,如果为空则创建实例
if (instance == nullptr) {
instance = new Singleton();
}
return instance;
}
// 删除拷贝构造函数和拷贝赋值运算符,防止被复制
Singleton(const Singleton&) = delete;
Singleton& operator=(const Singleton&) = delete;
};
Singleton* Singleton::instance = nullptr; // 初始化静态成员变量
int main() {
// 获取单例实例
Singleton* singleton1 = Singleton::getInstance();
Singleton* singleton2 = Singleton::getInstance();
// 判断两个实例是否相同
if (singleton1 == singleton2) {
cout << "两个实例相同" << endl;
} else {
cout << "两个实例不相同" << endl;
}
return 0;
}
3.传统单例模式的线程安全问题
饿汉式是线程安全的,懒汉式不是
当多线程执行getInstance时候,如果线程A判断当前实例为空,线程B正好判断到也为空,就会申请资源;当线程A恢复了后,继续执行,也会申请内存空间;就会出现两个实例,这就会出现问题;
4.解决方法
4.1静态局部变量
cpp
class Singleton {
private:
Singleton() {}
public:
static Singleton* getInstance() {
static Singleton instance;
return &instance;
}
};
4.2加锁
cpp
class Singleton {
private:
// 静态成员变量,用于保存单例实例
static Singleton* instance;
// 构造函数私有化,防止外部创建实例
Singleton() {}
public:
// 静态成员函数,用于获取单例实例
static Singleton* getInstance() {
// 判断实例是否为空,如果为空则创建实例
Mutexlock lock(mutex);//加锁
if (instance == nullptr) {
instance = new Singleton();
}
return instance;
}
// 删除拷贝构造函数和拷贝赋值运算符,防止被复制
Singleton(const Singleton&) = delete;
Singleton& operator=(const Singleton&) = delete;
};
Singleton* Singleton::instance = nullptr; // 初始化静态成员变量
int main() {
// 获取单例实例
Singleton* singleton1 = Singleton::getInstance();
Singleton* singleton2 = Singleton::getInstance();
// 判断两个实例是否相同
if (singleton1 == singleton2) {
cout << "两个实例相同" << endl;
} else {
cout << "两个实例不相同" << endl;
}
return 0;
}
4.3双重检查锁(DCL)
cpp
class Singleton {
private:
// 静态成员变量,用于保存单例实例
static Singleton* instance;
// 构造函数私有化,防止外部创建实例
Singleton() {}
public:
// 静态成员函数,用于获取单例实例
static Singleton* getInstance() {
// 判断实例是否为空,如果为空则创建实例
if (instance == nullptr) {
Mutexlock lock(mutex);
if(instance==nullptr)
instance = new Singleton();
}
return instance;
}
// 删除拷贝构造函数和拷贝赋值运算符,防止被复制
Singleton(const Singleton&) = delete;
Singleton& operator=(const Singleton&) = delete;
};
Singleton* Singleton::instance = nullptr; // 初始化静态成员变量
int main() {
// 获取单例实例
Singleton* singleton1 = Singleton::getInstance();
Singleton* singleton2 = Singleton::getInstance();
// 判断两个实例是否相同
if (singleton1 == singleton2) {
cout << "两个实例相同" << endl;
} else {
cout << "两个实例不相同" << endl;
}
return 0;
}
4.4pthread_once
cpp
#include<iostream>
class singleton{
public:
static singleton& getinstance()
{
pthread_once(&ponce,init);//保证该函数只被执行一次
return instance;
}
private:
static void init()
{
instance=new singleton();
}
singleton(){}
~singleton(){}
static pthread_once_t ponce;
static singleton* instance;
};
singleton::ponce=PTHREAD_ONCE_INIT;
singleton::instance=nullptr;