标签:att collect div read 缺点 必须 总结 using 耦合
定义:确保一个类只有一个实例,并提供一个全局访问点来访问这个实例
简单的说,就是你有且只有一个女朋友(有多个女朋友的模式不是这里~~),并且你的女朋友很特殊,从来只听你的话,所以别人想和她交流(访问她)就必须通过你(全局访问点)来和她交流。
系统中用到单例模式的地方很多,比如Windows系统点击开始只能出现一个开始界面,Ctrl+Alt+. 只能出现一个资源管理器,每个进程有且对应唯一一个进程ID等等。单例模式是为了让资源得到最大化利用,不浪费资源。同时假如不采用此模式,就可能在不同时刻打开同一个界面,但界面中的内容又各不相同,因而用户极易产生误解,影响使用效率。因此单例模式在系统中的应用非常重要。
要点:a.某一个单例类只能有一个实例;
b.必须自行创建这个实例;
c.必须向系统提供这个实例;
结构:
实现:
1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Text; 5 6 namespace Singleton 7 { 8 class Singleton 9 { 10 private static Singleton instance = null;//静态私有成员变量 11 12 //私有构造函数 13 private Singleton() 14 { 15 Console.WriteLine("恭喜你,获得一个女朋友~~"); 16 } 17 18 //静态公有方法,返回实例 19 public static Singleton Getinstance() 20 { 21 if(instance == null)//没女朋友 22 instance = new Singleton();//生成一个吧 23 return instance;//有就返回当前的, 24 } 25 } 26 class Program 27 { 28 static void Main(string[] args) 29 { 30 Singleton s1 = Singleton.Getinstance(); 31 Singleton s2 = Singleton.Getinstance(); 32 if (s1 == s2) 33 { 34 Console.WriteLine("怎么能想要共有一个女朋友呢?S2 赶紧换一个吧..."); 35 } 36 } 37 } 38 }
结果:
刚看到这两个单例的名字时还是有点好笑的,如此这么生动形象呢,就好像饿汉式单身(连温饱都满足不了,何来女朋友呢),懒汉式(好吃懒做的,也很难...)不乱扯了,回主题。饿汉式单例正如饿汉一样,很饿很饿的人最想要的就是立即马上吃东西。因此饿汉式单例在定义静态变量时就实例化了单例类,因为实在太饿了啊,等不及了。
1 class EagetSingleton 2 { 3 private static EagetSingleton instance = new EagetSingleton();//静态变量实例化单例类 4 5 private EagetSingleton(){} 6 7 public static EagetSingleton GetInstance() 8 { 9 return instance; 10 } 11 }
懒汉式单例类则是在类第一次被引用时将自己实例化,单例类被加载时不会实例化,所以这很符合懒汉的气质~但是在这里要注意的是,在定义静态变量时没有实例化单例类,而是在第一次调用静态方法时实例化单例类,这就会产生问题,高并发,多线程实现懒汉式单例时会创建多个对象,从而违背了单例模式的设计意图。也就是还是要对女朋友的个数进行判断。这要怎么办呢?在多线程的情况下,就要对该代码段进行控制,即每次只让一个线程进入并创建实例,也就是相当于现在的“共享女友”,帮你拍照啊,陪你去看电影啊 ,巴拉巴拉。但是,该“共享女友”有且只有一个,即单例类的唯一实例。所以,土豪们(各个线程)得一个一个租用,上一个用完了下一个才能租用。因此代码如下:
1 class LazytSingleton 2 { 3 private static LazytSingleton instance = null; 4 private static readonly object synRoot = new object();//看做一个门。 5 //程序运行时创建只读辅助对象 6 7 private LazytSingleton(){} 8 9 public static LazytSingleton GetInstance() 10 { 11 if(instance == null)//在房间外问:房间里有人吗 ? 没人回应 ,可能没,可能下一秒有人进去 ,我却以为没人 12 { 13 lock(synRoot)//第二次判断 //把门关了,外面线程进不来,只能里面的出来,外面的才能进 14 { 15 if(instance == null)//继续问,房间里有人吗? 有就真的有,没有就真的没 16 { 17 instance = new LazytSingleton();//创建实例 18 } 19 } 20 } 21 } 22 }
二者比较:
优点:无需考虑多线程同时访问的问题,确保实例唯一性。调用速度和反应时间快于懒汉模式,因为饿汉一开始就创建,后面则直接拿来用就可以了。
缺点:不管单例对象是否需要,都会在类加载时创建,这样不如懒汉式单例,资源利用不高,且加载时间较长。如启动VS,Eclipse等,需要loading许多可能要的可能不要的,要等啊...
优点:第一次使用时创建,不会一直占用资源,即延迟加载。
缺点:必须考虑多线程问题,特别是单例类作为资源控制器时,会涉及资源初始化,也会耗费许多时间,也会出现多线程同时首次引用此类,造成拥堵,导致系能性能降低
标签:att collect div read 缺点 必须 总结 using 耦合
原文地址:https://www.cnblogs.com/ygsworld/p/10683483.html