bigtalk.jpg

第21章 有些类也需计划生育——单例模式

概念

单例模式保证一个类仅有一个对象实例,并且提供一个访问它的全局访问点。

其实全局对象貌似可以实现只有一个实例,但是却不能保证没有人再次创建这样的实例。最稳妥的方法就是将实例化放到类本身中进行,让类本身负责保证其对象的唯一性。

实现

实现单实例类Singleton, 包括:

  • 一个它本身类型的instance成员,此处就是该类唯一的一个实例,只初始化一次存于此,便于后续判断。
  • 一个私有的构造函数使得外部无法创建对象
  • 一个GetInstance公共接口,用来获取该实例(这里有一个判断分支,若没有实例化的时候调用私有构造函数实例化该类并将对象存于instance)。

注:GetInstance是静态方法。

单实例模式类图:

20_singleton.png

单实例模式客户端使用:

20_singleton_use.png

客户端使用的方式就是: Singleton.GetInstance(); , 除了控制唯一实例,还对唯一的实例进行受控访问。

其它

多线程中的锁定:

  1. GetInstance() 中,判断是否单实例前加锁,可以避免多个线程同时进入该函数的单实例判断,并同时创建对象。
  2. 双重锁定减少资源浪费:每次调用 GetInstance() 判断前都要加锁会浪费资源,加锁之前也进行单实例判断,这样若无两个进程同时进入判断就不用加锁了。
  3. 双重锁定形式: if(conxx) {lock(xxx); if(conxx) {new()}}; 两次 if(conxx), 第一次是为了减少锁的次数,第二次是防止多个进程同时创建。

注:这是在使用时创建单实例对象,叫做懒汉式单实例。

静态初始化:
直接在类中用静态成员的方式进行单实例创建: class Singleton{ static Singleton instance=new Singleton();...} 这样就不用双重锁定了,

这种借助语言运行环境实现单实例不用双重锁定的方式,叫做饿汉式单实例。