一、任务队列(Task Queue)
任务队列是一种常用的并发设计模式,用于将多个任务放入一个队列,然后由一个或多个工作线程来执行这些任务。
代码示例
#include <iostream>
using namespace std;
class TaskQueue {
public:
// 删除拷贝构造函数和赋值操作符
TaskQueue(const TaskQueue& t) = delete;
TaskQueue& operator=(const TaskQueue& t) = delete;
// 公共的获取单例对象的函数
static TaskQueue* getInstance() {
if (m_taskQ == nullptr) {
m_taskQ = new TaskQueue;
}
return m_taskQ;
}
// 成员函数
void print() {
cout << "我是单例对象的一个成员函数..." << endl;
}
private:
// 私有构造函数
TaskQueue() = default;
// 单例对象指针
static TaskQueue* m_taskQ;
};
// 初始化静态成员变量
TaskQueue* TaskQueue::m_taskQ = nullptr;
int main() {
// 获取单例对象并调用其成员函数
TaskQueue::getInstance()->print();
return 0;
}
二、单例模式(Singleton Pattern)
单例模式确保一个类只有一个实例,并提供全局访问点
单例模式主要用于解决以下几种类型的问题:
1. 全局唯一实例
当一个类应该只有一个实例时,使用单例模式确保这一点。这通常适用于数据库连接、日志记录或应用程序的设置和配置。
2. 节约资源
创建对象通常需要消耗系统资源,如内存、CPU时间等。如果一个对象被频繁地创建和销毁,但每次都提供相同的功能,那么这种资源消耗是没有意义的。单例模式可以避免这种无意义的资源浪费。
3. 控制共享资源的访问
当多个对象需要访问共享资源(如数据库连接或网络套接字)时,单例模式可以帮助在整个系统范围内控制对这些资源的访问。
4. 保证结果一致性
如果多个实例可能会导致不一致的结果或状态冲突,那么确保一个类只有一个实例可能是有意义的。这样可以更容易地同步操作和状态。
5. 全局状态管理
在某些应用场景中,您可能需要全局状态管理。使用单例模式,您可以在一个地方管理这种全局状态,而不是将状态散布在多个对象中。
6. 延迟初始化
在某些情况下,初始化某个对象的成本可能很高,而应用程序可能最终并不需要这个对象。使用单例模式的懒汉式初始化,对象只有在第一次被需要时才会被创建。
7. 线程安全
单例模式还可以设计为线程安全,以便在多线程环境下工作。
示例:
#include <iostream>
using namespace std;
class TaskQueue {
public:
// 删除拷贝构造函数和赋值操作符
TaskQueue(const TaskQueue& t) = delete;
TaskQueue& operator=(const TaskQueue& t) = delete;
// 公共的获取单例对象的函数
static TaskQueue* getInstance() {
if (m_taskQ == nullptr) {
m_taskQ = new TaskQueue;
}
return m_taskQ;
}
// 成员函数
void print() {
cout << "我是单例对象的一个成员函数..." << endl;
}
private:
// 私有构造函数
TaskQueue() = default;
// 单例对象指针
static TaskQueue* m_taskQ;
};
// 初始化静态成员变量
TaskQueue* TaskQueue::m_taskQ = nullptr;
int main() {
// 获取单例对象并调用其成员函数
TaskQueue::getInstance()->print();
return 0;
}
代码用途和意义
-
唯一实例创建:这个设计模式主要用于确保一个类只有一个实例存在。在多线程环境、数据库连接、日志记录或任何需要单一操作或单一资源访问的场景中尤为有用。
-
全局访问点:该模式提供了一个全局访问该唯一实例的方法(
getInstance()
函数)。这意味着无论在何处,都可以通过这个接口访问到这个唯一实例。 -
防止拷贝:代码通过删除拷贝构造函数和赋值运算符(
operator=
)来防止该类的实例被拷贝。这是一个确保只有一个实例存在的额外措施。 -
私有构造函数:构造函数是私有的,这意味着你不能通过
new
来创建一个新的实例,这也确保了类的唯一性。 -
成员函数演示:
print()
函数只是一个用于演示如何使用该唯一实例的成员函数。 -
静态成员变量:
m_taskQ
是一个静态成员变量,用于存储该类的唯一实例。静态成员意味着这个变量在所有对象间是共享的,这正是我们需要的。
下一章我们再介绍C++中单例模式的实现方法懒汉式、饿汉式、线程安全的懒汉式单例模式的创建。