单例模式是最常用到的设计模式之一,熟悉设计模式的朋友对单例模式都不会陌生。一般介绍单例模式的书籍都会提到 饿汉式
和 懒汉式
这两种实现方式。下面接下来让我们一起来看看吧
简介
单例模式(Singleton Pattern)是 最简单的设计模式之一。这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。
这种模式涉及到一个单一的类,该类负责创建自己的对象,同时确保只有单个对象被创建。这个类提供了一种访问其唯一的对象的方式,可以直接访问,不需要实例化该类的对象。
注意:
- 1、单例类只能有一个实例。
- 2、单例类必须自己创建自己的唯一实例。
- 3、单例类必须给所有其他对象提供这一实例。
实现步骤:
- 将该类的构造方法定义为私有方法,这样其他处的代码就无法通过调用该类的构造方法来实例化该类的对象,只有通过该类提供的静态方法来得到该类的唯一实例;
- 在该类内提供一个静态方法,当我们调用这个方法时,如果类持有的引用不为空就返回这个引用,如果类保持的引用为空就创建该类的实例并将实例的引用赋予该类保持的引用。
模式实现:
懒汉式(线程不安全)
class SingleTon
{
public:
static SingleTon* getInstance()
{
if (psingle == NULL)
{
psingle = new SingleTon();
}
}
private:
SingleTon(){}
SingleTon(const SingleTon&);
static SingleTon* psingle;
};
SingleTon* SingleTon::psingle = NULL;
这种方式是最基本的实现方式,这种实现最大的问题就是不支持多线程。因为没有加锁 synchronized,所以严格意义上它并不算单例模式。
这种方式 lazy loading 很明显,不要求线程安全,在多线程不能正常工作。
懒汉式(加锁双重检查版)
class SingleTon
{
public:
static SingleTon* getInstance()
{
if (psingle == NULL)
{
lock();
if (psingle == NULL)
{
psingle = new SingleTon();
}
unlock();
}
return psingle;
}
private:
SingleTon(){}
SingleTon(const SingleTon&);
static SingleTon* psingle;
};
SingleTon* SingleTon::psingle = NULL;
这种方式采用双锁机制,安全且在多线程情况下能保持高性能。
饿汉模式
class SingleTon
{
public:
static SingleTon* getInstance()
{
return psingle;
}
private:
SingleTon(){}
SingleTon(const SingleTon&);
static SingleTon* psingle;
};
SingleTon* SingleTon::psingle = new SingleTon();
这种方式比较常用,但容易产生垃圾对象。
优点:没有加锁,执行效率会提高。
缺点:类加载时就初始化,浪费内存。