c#设想形式之单例形式
2019-11-18杂谈搜奇网39°c
A+ A-c#设想形式之单例形式
场景形貌
单例形式关于我们来讲一点也不形式,是一个罕见的称号,单例形式在顺序中的现实效果就是:确保一个顺序中只要一个实例,并供应一个全局接见点,节约体系资源
单例形式无论是在现实开辟中照样在软件运用中比较罕见,比方,windows体系的使命治理器、IIS的HttpApplication、现实项目中的日记组件等等
完成体式格局
单例形式为了完成一个实例,那末只要不把实例建立暴露出去,只经由过程类自身来建立实例,为了完成效果,须要定义一个私有组织函数
单例形式完成体式格局有:饿汉式、懒汉式、两重考证式、静态内部类、耽误加载(Lazy)
下面分别对每一种完成体式格局做一个简朴的实例,以及其优瑕玷
饿汉式
/// <summary> /// 建立一个 Singleton 类(饿汉式) /// 这类体式格局比较经常运用,但轻易发生垃圾对象。 ///长处:没有加锁,实行效力会进步。 ///瑕玷:类加载时就初始化,糟蹋内存。 ///它基于 classloder 机制防止了多线程的同步题目,不过,instance 在类装载时就实例化, ///虽然致使类装载的缘由有很多种,在单例形式中大多半都是挪用 getInstance 要领, ///然则也不能肯定有其他的体式格局(或许其他的静态要领)致使类装载,这时刻初始化 instance 明显没有到达 lazy loading 的效果。 /// </summary> public class SingleObject { //建立 SingleObject 的一个对象 private static SingleObject instance = new SingleObject(); //让组织函数为 private,如许该类就不会被实例化 private SingleObject() { Console.WriteLine("我被建立了.饿汉式"); } //猎取唯一可用的对象 public static SingleObject GetInstance() { return instance; } public void ShowMessage() { Console.WriteLine("Hello World.饿汉式"); } }
懒汉式
/// <summary> /// 建立一个 Singleton 类(懒汉式) /// 这类体式格局具有很好的 lazy loading,可以在多线程中很好的事情,然则,效力很低,99% 情况下不须要同步。 /// 长处:第一次挪用才初始化,防止内存糟蹋。 /// 瑕玷:懒汉式在单个线程中没有题目,但多个线程同事接见的时刻就可能同事建立多个实例,而且这多个实例不是同一个对象。 /// </summary> public class SingleObject1 { //建立 SingleObject 的一个对象 private static SingleObject1 instance; //让组织函数为 private,如许该类就不会被实例化 private SingleObject1() { } //猎取唯一可用的对象 public static SingleObject1 GetInstance() { if (instance == null) { instance = new SingleObject1(); Console.WriteLine("我被建立了.懒汉式"); } return instance; } public void ShowMessage() { Console.WriteLine("Hello World.懒汉式"); } }
两重考证式
/// <summary> /// 建立一个 Singleton 类(两重考证) /// 这类体式格局具有很好的 lazy loading,可以在多线程中很好的事情,然则,效力很低,99% 情况下不须要同步。 /// 长处:第一次挪用才初始化,防止内存糟蹋,线程平安。 /// 瑕玷:必需加锁 synchronized 才保证单例,但加锁会影响效力。 /// </summary> public class SingleObject2 { //建立 SingleObject 的一个对象 private static SingleObject2 instance; // 定义一个标识确保线程同步 private static readonly object locker = new object(); //让组织函数为 private,如许该类就不会被实例化 private SingleObject2() { } //猎取唯一可用的对象 public static SingleObject2 GetInstance() { //// 假如为空,那末就加锁,建立实例 if (instance == null) { lock (locker) { //// 桎梏胜利后,在做一次非空推断,防止在加锁时期以建立了实例而致使反复建立 if (instance == null) { instance = new SingleObject2(); Console.WriteLine("我被建立了.两重考证"); } } } return instance; } public void ShowMessage() { Console.WriteLine("Hello World.两重考证"); } }
静态内部类
/// <summary> /// 建立一个 Singleton 类(静态内部类) /// 这类体式格局不必加锁,在效力上和内存运用上都比较优异 /// 克服了饿汉形式的不足饿汉形式实行效力高,因为在类加载的时刻初始化致使内存糟蹋 /// </summary> public class SingletonStatic { /// <summary> /// 内部类 /// </summary> public class SingletonStaticInner { /// <summary> /// 当一个类有静态组织函数时,它的静态成员变量不会被beforefieldinit润饰 /// 就会确保在被援用的时刻才会实例化,而不是顺序启动的时刻实例化 /// </summary> static SingletonStaticInner() { } /// <summary> /// 实例化 /// </summary> internal static SingletonStatic singletonStatic = new SingletonStatic(); } /// <summary> /// 私有组织函数 /// </summary> private SingletonStatic() { Console.WriteLine("我被建立了.静态内部类"); } /// <summary> /// 猎取实例 /// </summary> /// <returns></returns> public static SingletonStatic GetInstance() { return SingletonStaticInner.singletonStatic; } public void ShowMessage() { Console.WriteLine("Hello World.静态内部类"); } }
耽误加载(Lazy)
/// <summary> /// 建立一个 Singleton 类(Lazy) /// 该体式格局是须要.netformwork4+ /// </summary> public class SingletonLazy { private static Lazy<SingletonLazy> singletonLazy = new Lazy<SingletonLazy>(()=>new SingletonLazy()); /// <summary> /// 私有组织函数 /// </summary> private SingletonLazy() { Console.WriteLine("我被建立了.Lazy"); } /// <summary> /// 猎取实例 /// </summary> /// <returns></returns> public static SingletonLazy GetInstance() { return singletonLazy.Value; } public void ShowMessage() { Console.WriteLine("Hello World.Lazy"); } }
每一种建立体式格局测试
建立一个掌握台顺序,经由过程多线程对每一种完成体式格局运用,检察其实例次数剖析:
/* 引见 企图:保证一个类唯一一个实例,并供应一个接见它的全局接见点。 重要处理:一个全局运用的类频仍地建立与烧毁。 什么时候运用:当您想掌握实例数量,节约体系资源的时刻。 怎样处理:推断体系是不是已经有这个单例,假如有则返回,假如没有则建立。 症结代码:组织函数是私有的。 运用实例: 典范的已有运用: 1、windows的使命治理器等 2、IIS的HttpApplication,一切的HttpModule都同享一个HttpApplication实例 在项目中的现实运用场景: 1、日记组件 2、多线程线程池治理 3、网站计数器 4、配置文件治理 */ class Program { static void Main(string[] args) { TaskFactory taskFactory = new TaskFactory(); List<Task> taskList = new List<Task>(); //// 测试--饿汉式 for (int i = 0; i < 5; i++) { taskList.Add(taskFactory.StartNew(() => { SingleObject.GetInstance(); })); } //// 测试--懒汉式 for (int i = 0; i < 5; i++) { taskList.Add(taskFactory.StartNew(() => { SingleObject1.GetInstance(); })); } //// 测试--两重考证 for (int i = 0; i < 5; i++) { taskList.Add(taskFactory.StartNew(() => { SingleObject2.GetInstance(); })); } //// 测试--静态内部类 for (int i = 0; i < 5; i++) { taskList.Add(taskFactory.StartNew(() => { SingletonStatic.GetInstance(); })); } //// 测试--Lazy for (int i = 0; i < 5; i++) { taskList.Add(taskFactory.StartNew(() => { SingletonLazy.GetInstance(); })); } Console.ReadLine(); } }
运转效果:
总结
依据单例形式是每一种完成体式格局对照剖析,在现实运用过程当中:发起采纳耽误加载(Lazy)
固然,另有其他相似的完成单例的体式格局,没有写到的,也迎接人人一同交换,勿喷
未定义标签