设计模式---单例模式

来源:互联网 发布:淘宝公司内部员工管理 编辑:程序博客网 时间:2024/06/07 10:05

设计模式—单例模式


1、学习框架

单例模式框架


2、为什么需要单例模式?

在我们日常的工作中经常需要在应用程序中保持一个唯一的实例,如:IO处理,数据库操作等,由于这些对象都要占用重要的系统资源,所以我们必须限制这些实例的创建或始终使用一个公共的实例,这就是我所分享的设计模式—单例模式(Singleton)

单例模式需要确保某个类中只有一个实例,而且自行实例化并向整个系统提供这个实例。

2.1、单例模式常见的应用场景

场景 具体使用 网站 计数器 web应用 配置管理器 应用程序 日志管理系统 数据库 连接池 多线程 线程池 资源性应用 内存池 操作系统 文件系统或打印机

2.2、单例类的特点

  • 单例类只能有一个实例
  • 单例类必须自己创建自己的唯一实例
  • 单例类必须给所有其它对象提供这一实例

3、什么是单例模式?

3.1、单例模式的概念

单例模式(Singleton):保证一个类仅有一个实例,并提供一个访问它的全局访问点。

3.2、单例模式结构图

单例模式是几个创建模式中最对立的一个,它的主要特点不是根据用户程序调用生成一个新的实例,而是控制某个类型的实例唯一性,我们可以通过看如下图,知道该模式所包含的角色只有一个,就是Singleton,它拥有一个私有构造函数,这确保用户无法通过new直接实例它。除此之外,该模式中包含一个静态私有成员变量和静态公有方法,该方法负责检验并实例化自己,然后存储在静态成员变量中,以确保只有一个实例被创建。
单例模式结构图
单例模式结构图


4、如何实现单例模式?

这里主要介绍饿汉式实现懒汉式实现,这两种实现方式的特点如下所示:

实现方式 优点 特点 饿汉式实现 加载进程时,静态创建单例对象,线程安全 无论使用与否,总是需要创建 懒汉式实现 用则创建,不用不创建,什么时间用什么事件创建 首次访问时动态创建单例对象,在多线程应用中,存在线程不安全的问题

4.1、饿汉式实现方式

将单例类的唯一对象实例,实现为其静态成员变量

class Singleton{private:  //私有的构造函数  Singleton();  //私有的拷贝函数  Singleton(const Singleton &);public:  static Singleton &getInstance()  {    return instance;  }private:  //创建静态成员变量  static Singleton instance;};

4.2、懒汉式实现方式

直到第一次使用,才创建单例类的唯一对象实例

class Singleton{private:  //私有的构造函数  Singleton();  //私有的拷贝函数  Singleton(const Singleton &);public:  static Singleton &getInstance()  {    //首次instance为NULL时,执行new    if (instance == NULL) {      instance = new Singleton;    }    return *instance;  }private:  //创建静态成员变量  static Singleton *instance = NULL;};

4.3、考虑线程安全的单例模式

借助互斥锁防止单例对象在不同线程中被重复创建

//创建互斥锁pthread_mutex_t Singleton::mutex = PTHREAD_MUTEX_INITIALIZER;class Singleton{private:  //私有的构造函数  Singleton();  //私有的拷贝函数  Singleton(const Singleton &);public:  static Singleton &getInstance()  {    //首次instance为NULL时,执行new    //添加互斥锁,防止单例对象在不同的线程中被重复创建    pthread_mutex_lock(&mutex);    if (instance == NULL) {      instance = new Singleton;    }    pthread_mutex_unlock(&mutex);    return *instance;  }private:  //创建静态成员变量  static Singleton *instance = NULL;};//优化://因为在第一次进行instance判断时,加锁可能起作用,但是在以后instance不为空时,可能造成性能的损失,故进行优化。public:  static Singleton &getInstance()  {    //首次instance为NULL时,执行new    //仅在单利对象未创建时加锁,提高效率    if (!instance) {      pthread_mutex_lock(&mutex);      if (instance == NULL) {//这个if判断不可省略,防止在其他线程中在创建实例        instance = new Singleton;      }      pthread_mutex_unlock(&mutex);    }    return *instance;  }

5、什么是线程安全

如果代码所在的进程中有多个线程在同时运行,而这些线程可能会同时运行这段代码。如果每次运行结果和单线程运行的结果是一样的,而且其他的变量的值也和预期的是一样的,就是线程安全的。

或者说:一个类或者程序所提供的接口对于线程来说是原子操作,或者多个线程之间的切换不会导致该接口的执行结果存在二义性,那就是线程安全。

原创粉丝点击