6.1单件模式定义:
确保一个类只有一个实例,并提供一个全局访问点。
6.2单件模式UML类图:
6.3应用场景
在软件开发中有很多对象我们只需要一个,如:线程池,缓存,对话框,注册表对象,日志对象等等,当我们想让某些类只能产生一个对象时,就可以采用单件模式。
6.4单件模式分析与实现(c#描述)
Using System.Runtime.CompilerServices;
//Singleton模式普通实现方式(非线程安全)
public class Singleton
{
private Singleton() {}
private static Singleton UniqueInstance;
public static Singleton GetInstance()
{
if (UniqueInstance == null)//此处代码非线程安全,多线程如果同时到达该点有可能New出多个单件。
{
UniqueInstance = new Singleton();
}
return UniqueInstance;
}
}
namespace SingletonForThreadSafe1
{
public class Singleton
{
private Singleton() { }
private static Singleton UniqueInstance;
//[MethodImpl(MethodImplOptions.Synchronized)] using System.Runtime.CompilerServices;
//[MethodImpl(MethodImplOptions.Synchronized)]确保该方法不可能有2个线程同时进入,当其它线程想要进入该代码段时,必须等待已有的线程离开才行。缺点是每次都要互斥,影响性能。
public static Singleton GetInstance()//现在整个GetInstance()方法为临界区。
{
if (UniqueInstance == null)
{
UniqueInstance = new Singleton();
}
return UniqueInstance;
}
}
}
namespace SingletonForThreadSafe2
{
//Singleton模式线程安全的实现方式2
public class Singleton
{
private Singleton() { }
private static Singleton UniqueInstance = new Singleton();//在静态初始化器中创建单件,此处代码是线程安全的,但缺点是如果Singleton对象是一个大对象,而静态初始化器在没有用到该对象的时候就new了一个出来,非常浪费内存空间。
public static Singleton GetInstance()
{
return UniqueInstance;
}
}
}
namespace SingletonForThreadSafe3
{
//Singleton模式线程安全的实现方式3
public class Singleton
{
private Singleton() { }
private volatile static Singleton UniqueInstance;
public static Singleton GetInstance()
{
if (UniqueInstance == null)
{
lock (UniqueInstance)//表示该段代码为同步区块,这样只有单件从未创建的第一次会同步,而以后不会同步,提高了性能。
{
if (UniqueInstance == null)//进入区块后,再检查一次,如果仍是null,则创建一个单件。
{
return new Singleton();
}
}
}
return UniqueInstance;
}
}
}
//调用类
public class Singleton_Test
{
public static void Do()
{
Singleton lobj_Singleton1 = Singleton.GetInstance();//这个单件不是线程安全的。
SingletonForThreadSafe1.Singleton lobj_Singleton2 = SingletonForThreadSafe1.Singleton.GetInstance();//线程安全的实现方式1
SingletonForThreadSafe2.Singleton lobj_Singleton3 = SingletonForThreadSafe2.Singleton.GetInstance();//线程安全的实现方式2
SingletonForThreadSafe3.Singleton lobj_Singleton4 = SingletonForThreadSafe3.Singleton.GetInstance();//线程安全的实现方式3
}
}