Singleton-单例模式
单例模式算得上是设计模式中最简单的模式,不过简单的单例模式也有不简单的地方。在系统运行中实现只存在唯一实例,就得使用单例模式,然后程序中缓存数据管理类、配置数据管理类都是此类需要存在唯一实例的,就像windows操作系统的资源管理器一样。
这里介绍两种方案,一种是使用双重判断支持泛型的方案,还有一种就是使用IODH(initialization-on-demand holder) 延迟加载单例模式,这种方案主要借助 静态成员来实现,不过不支持泛型。
直接上代码:
public static class Singleton<T> where T : class { private static volatile T _instance; private static object _lock = new object(); [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1000:DoNotDeclareStaticMembersOnGenericTypes")] public static T Instance { get { if (_instance == null) { lock (_lock) { if (_instance == null) { Type type = typeof(T); ConstructorInfo ctor; ctor = type.GetConstructor(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, null, new Type[0], new ParameterModifier[0]); _instance = (T)ctor.Invoke(new object[0]); } } } return _instance; } } } /// <summary> /// 性能最差 /// </summary> public static class Singleton { private static class Storage<T> where T : class { internal static volatile T _instance; } private static object _lock = new object(); [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1004:GenericMethodsShouldProvideTypeParameter")] public static T GetInstance<T>() where T : class { if (Storage<T>._instance == null) { lock (_lock) { if (Storage<T>._instance == null) { Type type = typeof(T); ConstructorInfo ctor; ctor = type.GetConstructor(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, null, new Type[0], new ParameterModifier[0]); Storage<T>._instance = (T)ctor.Invoke(new object[0]); } } } return Storage<T>._instance; } } /// <summary> /// 性能最佳 /// </summary> public class IODHSingletonWithInnerClass { private IODHSingletonWithInnerClass() { } private static class HolderClass { public static readonly IODHSingletonWithInnerClass instance = new IODHSingletonWithInnerClass(); } public static IODHSingletonWithInnerClass GetInstance() { return HolderClass.instance; } } public class IODHSingletonWithoutInnerClass { private IODHSingletonWithoutInnerClass() { } private static readonly IODHSingletonWithoutInnerClass instance = new IODHSingletonWithoutInnerClass(); public static IODHSingletonWithoutInnerClass GetInstance() { return instance; } }
int Maximum = 1000000; Stopwatch sw = Stopwatch.StartNew(); for (int i = 0; i < Maximum; i++) { SoruceManager soruceManager1 = Singleton.GetInstance<SoruceManager>(); } sw.Stop(); long timeUsedFirstWay = sw.ElapsedTicks; sw = Stopwatch.StartNew(); for (int i = 0; i < Maximum; i++) { SoruceManager soruceManager1 = Singleton<SoruceManager>.Instance; } sw.Stop(); long timeUsedSecondWay = sw.ElapsedTicks; sw = Stopwatch.StartNew(); for (int i = 0; i < Maximum; i++) { IODHSingletonWithoutInnerClass singleton = IODHSingletonWithoutInnerClass.GetInstance(); } sw.Stop(); long timeUsedThirdWay = sw.ElapsedTicks; sw = Stopwatch.StartNew(); for (int i = 0; i < Maximum; i++) { IODHSingletonWithInnerClass singleton = IODHSingletonWithInnerClass.GetInstance(); } sw.Stop(); long timeUsedFourthWay = sw.ElapsedTicks; MessageBox.Show(string.Format("Singleton.GetInstance<SoruceManager>() 执行{0}次花费:{1}。\r\nSingleton<SoruceManager>.Instance执行{0}次花费:{2}。\r\nIODHSingletonWithoutInnerClass.GetInstance()执行{0}次花费:{3}。\r\nIODHSingletonWithInnerClass.GetInstance()执行{0}次花费:{4}。",Maximum, timeUsedFirstWay,timeUsedSecondWay,timeUsedThirdWay,timeUsedFourthWay));
使用上面的代码进行多次测试,发现使用IODH方案性能最佳,是否使用内部类差异性不大。
本文来自博客园,作者:业荒于嬉,转载请注明原文链接:https://www.cnblogs.com/FreeLoopPowter/p/15572365.html
如内容对您有所帮助,还请不吝推荐一下!