Murphy

谈谈单例模式

电脑版发表于:2020/3/19 12:11

设计模式分为三类:创建型、结构性、行为型。

今天就谈一下创建型中的单例模式,什么觉创建型?创建型简单的来说就是关注于类的创建。

下面直接开始撸代码

创建一个控制台程序,建一个Singleton类

这里我们建了一个构造函数,假设他很费时间,构造一次就打印一次消息

运行,我们看看结果

可以看到,每实例化一次,就会打印一次,那是不是很浪费资源,这个时候单例模式就可以解决这个问题了,我们改造一下代码

好,这个就改造好了,我们看一下结果

这里可以看到,我们调用五次,实际上他只实例化一次,这就是单例模式了,好像是没毛病了,但是有一个情况没有考虑到,那就是线程。我们现在是单线程的,当然没问题了,多线程的情况下,我们这个代码能正常嘛,我们试一下。

结果显而易见,被构造了五次,那怎么办呢,办法还是有的,加锁,现在网上搜一堆都能看到加锁

为了形象一点,我们再写一个show方法来调一下

看下结果

ok,完美解决,但是仔细想想,调用五次,每个线程都要在锁那里等待完成,那不是不管这个Singleton有没有被实例化,只有要我调用,那一定就会等待,那怎么办呢,这个时候有个办法就可以解决,双重判断,记得我第一次上网搜索单例模式的时候看到这个完全懵逼,不知道是怎么是做什么的

好,现在来假设一下,当我第一次进来的时候,没有被实例化,五个红色的都能进入第一个判断,然后等待第一个完成这一系列操作,然后我在调一次,这次是五个蓝色的,第一层判断的时候就到头了,因为前面的那次调用已经实例化一次了,所以这里减少了等待的时间,直接从内存中读取,提升性能。

这种模式被称为懒汉模式,还有一种叫饿汉模式

比如这个,一个静态的构造函数,会在实例化Singleton之前由CLR调用一次,而且只会调用一次。所以就不存在多线程的困扰。

只要你调用提供给外界的方法,就直接返回Singleton。这里说一下,静态字段要比静态方法先执行,看代码就能看出来,我是先定义,后赋值的。结果就截图了,这种简单的例子脑海中转一下就OK了;

总结:单例模式保证在进程中唯一,也就是说当进程启动,永远不会释放内存,知道进程停止,所以千万不要有想法每个类都来个单例模式,毕竟设计模式这种高大上的东西对吧。单例模式要在特定的环境下使用,能不用就不用,比如数据库的连接池,缓存等等这些这些可以使用。


关于TNBLOG
TNBLOG,技术分享。技术交流:群号677373950
ICP备案 :渝ICP备18016597号-1
App store Android
精彩评论
{{item.replyName}}
{{item.content}}
{{item.time}}
{{subpj.replyName}}
@{{subpj.beReplyName}}{{subpj.content}}
{{subpj.time}}
猜你喜欢