单例模式:单例对象(Singleton)是一种常用的设计模式。在Java应用中,单例对象能保证在一个JVM中,该对象只有一个实例存在。这样的模式有几个好处:
1、某些类创建比较频繁,对于一些大型的对象,这是一笔很大的系统开销。
2、省去了new操作符,降低了系统内存的使用频率,减轻GC压力。
3、有些类如交易所的核心交易引擎,控制着交易流程,如果该类可以创建多个的话,系统完全乱了。(比如一个军队出现了多个司令员同时指挥,肯定会乱成一团),所以只有使用单例模式,才能保证核心交易服务器独立控制整个流程。
我们建立的一些类是属于工具性质的,基本不用存储太多的跟自身有关的数据,在这种情况下,
每次都去new一个对象,即增加了开销,也使得代码更加臃肿。其实,我们只需要一个实例对象就可以。如果采用全局或者静态变量的方式,会影响封装性,难以保证别的代码不会对全局变量造成影响。考虑到这些需要,我们将默认的构造函数声明为私有的,这样就不会被外部所new了,甚至可以将析构函数也声明为私有的,这样就只有自己能够删除自己了
若将对一个类使用单利模式,只需要在该类的instance函数中使用 return Singleton<类名>::Instance();
1、某些类创建比较频繁,对于一些大型的对象,这是一笔很大的系统开销。
2、省去了new操作符,降低了系统内存的使用频率,减轻GC压力。
3、有些类如交易所的核心交易引擎,控制着交易流程,如果该类可以创建多个的话,系统完全乱了。(比如一个军队出现了多个司令员同时指挥,肯定会乱成一团),所以只有使用单例模式,才能保证核心交易服务器独立控制整个流程。
我们建立的一些类是属于工具性质的,基本不用存储太多的跟自身有关的数据,在这种情况下,
每次都去new一个对象,即增加了开销,也使得代码更加臃肿。其实,我们只需要一个实例对象就可以。如果采用全局或者静态变量的方式,会影响封装性,难以保证别的代码不会对全局变量造成影响。考虑到这些需要,我们将默认的构造函数声明为私有的,这样就不会被外部所new了,甚至可以将析构函数也声明为私有的,这样就只有自己能够删除自己了
单线程中:
static Singleton *instance = NULL;
Singleton* getInstance()
{
if (instance == NULL)
instance = new Singleton();
return instance;
}
这样就可以了,保证只取得了一个实例。但是在多线程的环境下却不行了,因为很可能两个线程同时运行到if (instance == NULL)这一句,导致可能会产生两个实例。于是就要在代码中加锁。
Singleton* getInstance()
{
if (instance == NULL)
{
lock();
if(instance == NULL)
{
instance = new Singleton();
}
unlock();
}
return instance;
}
为何这样加,主要跟效率有关,前面一个if(instance == NULL)能将那些instance != NULL排除在外,只加锁需要加锁的,从而提高效率
模板方法实现的单例模式
template <typename T>
class Singleton
{
private:
Singleton() {}
Singleton(const Singleton& rhs);
Singleton& operator=(const Singleton& rhs);
public:
static T * GetInstance()
{
if(m_pInstans == NULL)
{
lock();
if(m_pInstans == NULL)
{
m_pInstans = new T();
}
unlock();
}
return m_pInstans ;
}
private :
static T * m_pInstance;
};
若将对一个类使用单利模式,只需要在该类的instance函数中使用 return Singleton<类名>::Instance();
如实现commandManager类:
class CommandManager : public BaseCommandManager, public Subject
{
friend class Singleton<CommandManager>;
private:
CommandManager();
~CommandManager();
CommandManager(const CommandManager& rhs);
CommandManager& operator=(const CommandManager& rhs);
public:
static CommandManager * Instance();
};
CommandManager * CommandManager::Instance()
{
return Singleton<CommandManager>::Instance();
}