自从学程序设计以来,总是时不时的能够听得到设计模式这个词,在“小白”眼里,这个词就像是和框架一样,让人一听就蒙,也确实,对于这些设计模式,你不得不叹服它的巧妙灵活,用起来异常好用。我也是会时不时地去百度里面去看下一些大牛们写的关于设计模式的博客,对于一些常用的设计模式也是用得挺多,在这里写篇博客,来加深一下自己对这些模式的记忆,也学习一下那么比较陌生和不知道的设计模式。
单例模式,这个应该算是设计模式中比较容易理解和使用的一个设计模式了。
在写这篇博客之前,我专门在百度上搜索了一下设计模式,并复习了一遍,巧合得发现了一个C#的单例模式,写得很细心,也是深有感触,在这里分享一下。
单例模式,就是有些类我们希望它只有一个实例,就像我们玩游戏的时候有社团,帮派,我们希望一个帮派里面只有一个团长,一个帮主一样。
话不多说,先上代码,知道单例模式的人基本也都知道这么一个单例模式的构建。
这段代码中,我们可以看到,有一个静态字段和属性,他的类型和我们要实现单例的类是一样的,这样,我们就可以通过类来直接获得到我们静态的SingleInstance类型对象,同时,我们还有一个私有的构造函数,也就是这个构造函数,让这个类外面不能实例化我们需要实现单例的类,使的我们只能调用这个类中的Instance来获取SingleInstance对象,也就完成了单例的实现。
在单线程中,这确实是一个无可挑剔的单例,但是在多线程中,可能就不是这么回事了,由于我们CPU的执行是分配时间来执行一个线程,可能我们一个线程执行到if(instance == null)之后,直接跳到另一个线程,那么两个线程可能都判断if(instance == null)为真,也就创建了两个instance实例,也就不是我们想要的单例了。
那么,上述问题怎么解决?这时候,我们就要想到多线程中的一个关键字——lock,我们在判断instance == null之前用一个空对象来锁住我们的判断,那么就使的只有一个线程在判断instance == null。
下面,上代码:
修改的就是这段代码,申明了一个空对象locker,用于标记是否进行判断,一旦locker被锁住,那么久说明有其他线程在进行判断,等到程序其他对象return instance,运行完这段之后才开始判断instance是否为空,这样,就不会出现两个线程都认为instance为空的情况,也不会产生两个单例对象,从而实现了多线程中的单例。
接下来,我们细看这段代码,每次都要对locker加锁,其实我们对locker锁了一次之后,也就油instance对象了,也就不用每次都去对locker加锁,那么也就增加了额外的开销,也损失了性能。那么,我们又要怎么解决这个问题呢。
我们可以用双重锁定,这个用语言来描述还是有点费尽,偷偷懒,上代码,一清二楚。
看着上面的代码,也就是多了一个if(instance == null)在最外层,从而先判断instance是否为空,如果为空,再锁定locker,实例化instance,这样,就完美解决了这个每次获取单例实例的时候都要锁住locker,只在第一次判断instance为空的时候才锁住。从而降低了内存开销。
楼主也是抱着学习的态度来记录自己的学习成果,如有错误欢迎指正,同时欢迎各路英雄与楼主一起讨论研究。