简述网站的制作流程,免费vps,推广关键词优化公司,制作网页的步骤#xff08;一#xff09;单例设计描述 只要了解过设计模式的同学都会知道#xff1a;单例设计模式#xff0c;大家都知道单例设计模式是一种创建行的设计模式。既然是创建型#xff0c;那么先来讲讲#xff0c;对象的创建的过程吧。 --静态成员#xff1a;静态成员在程… 一单例设计描述 只要了解过设计模式的同学都会知道单例设计模式大家都知道单例设计模式是一种创建行的设计模式。既然是创建型那么先来讲讲对象的创建的过程吧。 --静态成员静态成员在程序加载的时候就会加载进内存。 --实例成员只有new的时候才有实例成员。1、为实例的数据字段分配内存然后初始化对象的附加字段类型指针和同步索引块最后调用类型的实例构造器来设置对象的初始化状态。 单例模式一般用在一个类的创建对象很消耗资源消耗时间并且系统要保证只有一个对象的时候。一句话对象的创建并不是很耗时间不要刻意去套用单例模式单例模式必须是在单例的时候才单例。 二 单例模式的演变 下面我们来模拟实际情况 public class Singleton {/// summary/// 对象会持有资源/// /summaryprivate Liststring _connListnew Liststring(){测试数据库连接,测试数据库连接2,测试数据库连接3,测试数据库连接4};public Singleton(){long lResult 0;for (int i 0; i 100000; i){lResult i;}Thread.Sleep(1000);Console.WriteLine({0}被构造一次,this.GetType().Name);}public void Show(){Console.WriteLine(调用了Show);}} 这个类的创建需要耗费很多资源里面有个Show方法。 那么接下来实际中我们可能有十个地方要用到这个类里面的Show方法我们的做法是这样的 //那么接下来我们这里要调用十次Show方法for (var i 0; i 10; i) {var singletonObj new Singleton();singletonObj.Show();} 这里每次调用一次都需要耗费很多资源和时间这里可能有些同学就会说那我把这个singletonObjnew Singleton()提取出来放到最外面来。 那行按照我们需要我们把var singletonObjnew Singletone()放到外面如下所示 貌似这样就解决了我们的问题但是各位你们想一想我们一个系统是有多个人开发的A这里这样做B可能不知道这里有这个声明那他可能就还是一样去New Singleton还是导致我们系统中存在大量这个对象。 我们应该要如何解决这个问题呢 如何保证这个对象在整个系统只被创建一次呢 单例模式--单线程 从上面的问题我们也可以看出因为谁都可以在New Singleton所以导致了这个问题。那按照这个想法那我们就想啦那就把构造函数私有化呗私有化完了之后我们应该还要提供一个方法或者啥的给外面调用也只能是静态的成员构造函数私有化了外面是不可以New了的 那就按照刚刚的说法我们来进行一次改进 public class Singleton {/// summary/// 对象会持有资源/// /summaryprivate Liststring _connListnew Liststring(){测试数据库连接,测试数据库连接2,测试数据库连接3,测试数据库连接4};private Singleton(){long lResult 0;for (int i 0; i 100000; i){lResult i;}Thread.Sleep(1000);Console.WriteLine({0}被构造一次,this.GetType().Name);}public static Singleton CreateInstance(){return new Singleton();}public void Show(){Console.WriteLine(调用了Show);}} 按照我们上面这个写法把构造函数私有化了然后在静态方法里面New Singletone(); 调用结果如下 for (var i 0; i 10; i) {var singletonObj Singleton.CreateInstance();singletonObj.Show();} //写进里面去了是为了模拟有十个不同的开发再调用 那结果还是没有达到我们想要的那现在问题就是对象没有重用因为我们每次new导致了对象没有做到重用那就让对象进行重用呗。最简单的方法就是给一个静态的字段为啥静态呢因为我们那边方法是静态的然后做一个判断如果对象为空那么我们就创建如果不为空就不用创建了如下所示。 我们在原来的基础上做了如上图的改进。结果如下 我们想要的结果实现了多次调用的时候做了重用对象只构造了一次。本来想着单例模式就这样结束了单线程是没有问题并且这种实现是一种懒汉式懒汉式当你需要用这个类的时候才会去实例化。 编程世界里面我们总是要考虑一下多线程的情况。 单例模式--多线程 这个是用Task.Run()开启了也给多线程的异步调用 for (var i 0; i 10; i){Task.Run((){var singletonObj Singleton.CreateInstance();singletonObj.Show();}); }Thread.Sleep(5000); 通过上面的结果我们可以看出我们的之前的做法在多线程环境还是会调用多次。 有些同学就会说用lock锁啦行我们就给他加上一把锁。 public class Singleton {/// summary/// 对象会持有资源/// /summaryprivate Liststring _connListnew Liststring(){测试数据库连接,测试数据库连接2,测试数据库连接3,测试数据库连接4};private static Singleton singletonObj null;private static readonly object singleTonObjLock new object(); //加锁之后这里为啥要用readonly大家可以找private Singleton(){long lResult 0;for (int i 0; i 100000; i){lResult i;}Thread.Sleep(1000);Console.WriteLine({0}被构造一次,this.GetType().Name);Console.WriteLine($线程{Thread.CurrentThread.ManagedThreadId}调用一次);}public static Singleton CreateInstance(){lock (singleTonObjLock) //很多同学都说用lock thisthis肯定是不行的因为lock是lock引用的如果这个this的引用改变了...{if (singletonObj null){singletonObj new Singleton();}}return singletonObj;}public void Show(){Console.WriteLine(调用了Show);}} 看我们给他加完锁的时候效果。 嗯实现了我们想要的效果了说明我们加锁是有效果的。到了这个时候大家可能觉得一个单例模式应该就快结束了那么我们再来看看这种情况。 单例模式--多线程双iflock) 通过上面的介绍我们理解了单例模式的演变过程也对单例模式多线程有了更加深刻的印象。 三单例模式其他实现 就像我们一开始说的那样单例模式其实一个进程内在多线程环境下如何保证只有一个对象这就是单例。也可以从这个定义看出我们可以通过静态的构造函数来实现一个单例模式。 静态构造函数是由CLR保证的有且只会加载一次。 其他很多方法实现都是利用static关键字的背后原因在第一次使用类型之前被调用且只会被调用一次。 四懒汉式饿汉式 懒汉就是说这个人很懒需要用的时候才构建。双iflock这种就属于懒汉式。懒汉式利用了延迟加载加载的思想。 饿汉就是调用我这个类型就会帮你创建好管你用不用我都会帮你创建就是饿了吗我后面介绍的利用static关键字的就是属于饿汉式饿汉式管你之前有没有内存中都会帮你new一个新的实例。 五单例模式的使用场景 单例必须单例才单例反正没必要。单例模式实现都有性能损失静态方法。 单例会把对象常驻内存静态的。 单例的使用多个人操作可能会对你影响因为都是对同一份引用进行修改。 一般用在数据库连接打印机远程服务调用等等这些大对象身上。 //单例模式的应用场景补充读取配置文件信息读取配置文件不应该一直new一个类应该是单例的。 public class ConfigV1{private static object _lockObj new object();private static ConfigV1 _instance;private static Dictionarystring,string _configItems new Dictionarystring, string();private ConfigV1(){Init();Console.WriteLine(${this.GetType().Name}被构造一次);}public static ConfigV1 GetInstance(){if (_instance null){lock (_lockObj){if (_instance null){_instancenew ConfigV1();}}}return _instance;}public string this[string item]{get{return _configItems[item];}}private void Init(){var configConfigurationManager.AppSettings.AllKeys;foreach(var key in config){_configItems.Add(key,ConfigurationManager.AppSettings[key]);}}} github:https://github.com/gdoujkzz/DesignPattern.git 谢谢你阅读我的博客如果有收获请点一个赞推荐 转载于:https://www.cnblogs.com/gdouzz/p/8319485.html