单例模式

来源:互联网 发布:虚拟机怎么设置网络 编辑:程序博客网 时间:2024/06/16 21:48

一、什么是单例模式
有时候我们会遇到这样一种情况,一个类只能有一个对象被实例化,这时我们就可以使用单例模式了。
单例模式通过类本身来管理其唯一实例。在设计这个类的时候,让他只能创建一个实例并提供对此实例的全局访问。因此单例模式有两个最基本的条件是,确保一个类只有一个实例被创建,提供一个对实例的全局访问指针。

二、常见的单例模式实现
常用的单例模式实现方法有两种,饿汉式和懒汉式。

懒汉式单例模式:
这里写图片描述
在懒汉模式下,直到用户第一次调用GetInstance()方法时才new出对象的实例,而之后再调用GetInstance()方法时,只会返回第一次创建出来的对象的地址,不会再去创建实例。这也就保证了一个类只有一个实例,并且提供了一个全局访问的指针。
但是上面的代码却存在内存泄漏和线程安全的问题。
1、首先是new出来的内存没有被释放,这个问题的解决方法如下:
这里写图片描述
可以在内部再声明一个内部类,用来管理实例的销毁。因为在程序运行时结束时,系统会销毁所有的全局变量。所以系统会调用CSingleton的静态成员_CGarbo的析构函数,该析构函数会删除单例的唯一实例。

2、在多线程下(NULL==_Instance)会存在线程安全问题,所以我们可以对它做同步的改进
这里写图片描述
上面代码加锁之后已经能解决线程安全的问题了,但是这个锁可能会带来性能问题。
因为只有在第一次调用GetInstance()之前才存在线程安全问题,因为这时牵扯到内存分配,但是在以后调用GetInstance()的时候不会存在线程安全问题了。在以后的调用中,如果再去申请锁的话会带来性能问题,尤其是当该函数调用多的时候。
这时候就有人想出来了double-check这种方法来解决性能问题:
这里写图片描述

饿汉式单例模式:
这里写图片描述
在饿汉模式下,类的唯一实例是在类创建的时候就被创建出来,因为这时候GetInstance方法内部有一个静态的类的实例。每次调用GetInstance方法的时候就会返回这个静态变量的地址,而且不存在内存泄漏可线程安全问题,所以推荐使用饿汉模式的单例模式。

原创粉丝点击