什么是设计模式?简而言之。就是一些大佬总结出来的经验,将一些常见的问题或场景,设计成一种套路,可以让后续的程序员快速设计自己的代码。
那么为什么我们需要用设计模式呢?
单例模式代码框架稳定,代码复用度高,比较容易理解。
常见的设计模式:
创建型模式:用于构建对象,将实现从系统中分离出来。
单例模式。
结构型模式:用于在许多不同的对象中形成大型的对象结构。
适配器模式
行为模式:管理对象
观察者模式
此处我们主要介绍的是单例模式。
单例模式
特点:
只提供唯一一个类的实例化,并且具有全局变量的特性,在任何地方都可以通过单例类提供的获取类实例化的方法来获取唯一的实例化。
使用场景:
数据池:用来缓存数据的数据结构,在不同的线程中进行读取和写入。
内存池:将用户使用完的内存自己维护起来,不用还给系统。这样申请内存效率及高。
怎么实现单例类呢?
1.全局只有一个实例,这就要用到static的特性,并同时用private禁止自己的构造函数、拷贝构造以及赋值运算符重载。
2.线程一定要安全。
3.给出实例的接口,使用static来修饰。
在单例模式中分为两种子模式:
饿汉模式
程序在初始化的时候进行实例化,并且资源就会在初始化阶段全部加载了。所以说,这种程序运行速度快,但是程序初始化的时候时间比较长。
懒汉模式
资源在使用的时候才去加载,换句话说对象在使用的时候前实例化。所以初始化比较快,但是运行速度不是很流畅。并且涉及线程安全问题。
此处大家可能有问题了?
1.为什么饿汉模式没有线程安全问题?
因为静态成员变量是在编译的时候存储在静态区,所以程序启动时,在其他线程还没有创建之前,就会先进行初始化。当其他线程被创建出来,已经初始化完成了,所以不牵扯线程安全问题。
2.懒汉模式如何保证线程安全?
1.互斥锁
2.双if判断
3.volatile关键字防止编译过度优化
懒汉模式代码:
class LH
{
static LH* GetLh();
private:
LH(){}
LH(const LH& l){}
LH operator = (const LH& lh){}
volatile static LH* lh;
static pthread_mutex_t mutex;
};
LH* LH::lh=nullptr;
LH* LH::GetLH()
{
if(lh == nullptr)//减少不必要的线程等待。
{
pthread_mutex_lock(&mutex);
if(lh == nullptr)
{
lh = new LH();
}
pthread_mutex_unlock(&mutex);
}
return lh;
}