Singleton Pattern -- 不一样的单例模式
Singleton Pattern -- 单例模式
单例模式是用来创建一个只能又一个实例的对象。
单例模式类图如下。

单例模式有两大好处:
(1)对于频繁使用的对象,可以省略创建对象所话费的时间,这对于那些重量级对象而言,是非常可观的一笔系统开销。
(2)由于new操作的次数减少,因而对系统内存的使用频率页会降低,这将减轻GC压力,缩短GC停顿时间。
因此对于系统的关键组件和被频繁使用的对象,使用单例模式便可以有效地改善系统的性能。
这种单例的实现方式非常简单,而且十分可靠,它唯一的不足仅是无法对instance实例做延迟加载。假如单例的创建过程很慢,而由于instance成员变量
是static定义的,因此在JVM加载单例类时,单例对象就会被建立,如果此时,这个单例类在系统中还扮演其他角色,那么在任何使用这个单例类的地方都会
初始化这个单例变量,而不管是否被用到。比如单例类作为String工厂,用于创建一些字符串(该类即用于创建单例Singleton,又用于创建String对象):
单例模式通用代码(饿汉模式):

当使用Singleton.createString()执行任务时,程序输出:

可以看到,虽然此时并没有使用单例类,但它还是被创建出来,这也许是开发人员所不愿意看到的。为了解决这个问题,并以此提高系统在相关函数调用是的
反应速度,就需要引入延时加载机制。
延时单例模式(懒汉模式)

首先,对于静态成员变量instance初始化赋值null,确保系统启动时没有额外的负载;其次,在getInstance()工厂方法中,判断当前单例是否已经存在,
若存在则返回,不存在则再建立单例。这里尤其还要注意,getInstance()方法必须是同步的,否则再多线程的环境下,当一个线程A执行到instance = new
Singleton(),但还没有获得对象(对象初始化时需要时间的),在此同时第二个线程B也在执行,执行到(instance == null)判断,那么线程B判断的结果
也为真。于是继续运行下去,线程A获得了一个对象,线程B也获得了一个对象,在内存中就出现了两个对象!
如下:

开启了5个线程同时完成以上代码的运行,使用第1种类型的单例耗时0ms,而使用LazySingleton,解决了线程安全问题却相对耗时约390ms。性能至
少相差2个数量级。
为了使用延时加载引入的同步关键字反而降低了系统性能,有点得不偿失,我们继续改进:
  
在这个实现中,单例模式是用来内部类来维护单例的实例,当StaticSingleton被加载时,其内部类并不会被初始化,故可以确保
StaticSingleton类被载入JVM时,不会初始化单例类,而当getInstance()方法被调用时,才会加载SingletonHolder,从而初始化instance。
同时,由于实例的建立是在类加载时完成,故天生对多线程友好,getInstance()方法也不需要使用同步关键字。因此,这种实现方式同时
兼备以上两种实现的优点。
通常情况下,用以上方式实现的单例已经可以确保在系统中只存在唯一实例了。
(现在已经标准的实现了单例模式方式有(单检查锁,双检查锁,枚举),但是如果我们通过反射机制调用,是否会产生多个实例,即破坏了单例模式。)
反射模式,调用方法是不会破坏单例模式,因为反射方法同样受锁&逻辑的保护。
调用构造函数会破坏单例模式,因为构造方法只是private 修饰,防止外部类访问,但是反射方法访问,不受限制。
还有一种破坏次单例模式的方法:对象克隆。这个现象是我在看原型模式时发现。
如果类实现了Clonable接口,那么在得到单例模式对象可以通过clone方法生成单例对象。
所以写单例模式时不要继承或间接继承Clonable接口。
Singleton Pattern -- 不一样的单例模式的更多相关文章
- Net设计模式实例之单例模式( Singleton Pattern)
		一.单例模式简介(Brief Introduction) 单例模式(Singleton Pattern),保证一个类只有一个实例,并提供一个访问它的全局访问点.单例模式因为Singleton封装它的唯 ... 
- 深入浅出设计模式——单例模式(Singleton Pattern)
		模式动机对于系统中的某些类来说,只有一个实例很重要,例如,一个系统中可以存在多个打印任务,但是只能有一个正在工作的任务:一个系统只能有一个窗口管理器或文件系统:一个系统只能有一个计时工具或ID(序号) ... 
- 浅谈设计模式--单例模式(Singleton Pattern)
		题外话:好久没写blog,做知识归纳整理了.本来设计模式就是个坑,各种文章也写烂了.不过,不是自己写的东西,缺少点知识的存在感.目前还没做到光看即能记住,得写.所以准备跳入设计模式这个大坑. 开篇先贡 ... 
- 设计模式之单例模式(Singleton Pattern)
		单例模式 单例模式(Singleton Pattern)在java中算是最常用的设计模式之一,主要用于控制控制类实例的数量,防止外部实例化或者修改.单例模式在某些场景下可以提高系统运行效率.实现中的主 ... 
- 深入设计模式(二)——单例模式(Singleton Pattern)
		一.单例模式介绍 单例模式(Singleton Pattern),保证一个类只有一个实例,并提供一个访问它的全局访问点.单例模式因为Singleton封装它的唯一实例,它就可以严格地控制客户怎样访问它 ... 
- 乐在其中设计模式(C#) - 单例模式(Singleton Pattern)
		原文:乐在其中设计模式(C#) - 单例模式(Singleton Pattern) [索引页][源码下载] 乐在其中设计模式(C#) - 单例模式(Singleton Pattern) 作者:weba ... 
- C#设计模式之一单例模式(Singleton Pattern)【创建型】
		一.引言 看了李建忠老师的讲的设计模式已经有一段时间了(这段时间大概有一年多了),自己还没有写过自己的.有关设计模式的文章.这次想写一些关于设计模式的文章,用自己的理解和代码来写,算是复习一遍 ... 
- 【wif系列】C#之单例模式(Singleton Pattern)最佳实践
		目录 前言 单例基类 单例提供者 总结 前言 在上一篇译文--<深入理解C#--在C#中实现单例模式>中,对在C#中实现单例模式进行了详细阐述.我们在日常的开发中可以采用解决方案4或解决方 ... 
- 【设计模式】单例模式 Singleton Pattern
		通常我们在写程序的时候会碰到一个类只允许在整个系统中只存在一个实例(Instance) 的情况, 比如说我们想做一计数器,统计某些接口调用的次数,通常我们的数据库连接也是只期望有一个实例.Windo ... 
随机推荐
- 卡耐基梅隆大学(CMU)元学习和元强化学习课程 | Elements of Meta-Learning
			Goals for the lecture: Introduction & overview of the key methods and developments. [Good starti ... 
- PyQt(Python+Qt)学习随笔:QTreeView树形视图的headerHiden属性
			老猿Python博文目录 专栏:使用PyQt开发图形界面Python应用 老猿Python博客地址 QTreeView树形视图的headerHiden属性用于控制视图中是否隐藏标题,为True隐藏,否 ... 
- Object.prototype.toString.call()为什么可以用来检测数据类型?
			obj.toString()方法是用来干什么的 每一个对象都有一个toString()方法,默认情况下toString()被每一个Object对象继承,如果此方法未被重写,toString()返回&q ... 
- 深海 => 暴力扫描挖掘机
			平时总是联动这个联动那个,写一些小脚本,感觉零碎又没啥意思,想把市面上一些比较知名的工具集合一下,弄个方便点的躺着挖洞的工具,看看效果会不会更好,暂时名字取深海吧,估计又是一个迟迟不填的坑,灌灌灌灌水 
- java中的反射(二)
			java中的反射(一):https://www.cnblogs.com/KeleLLXin/p/14060555.html 目录 一.反射 1.class类 2.访问字段 3.调用方法 4.调用构造方 ... 
- 深入分析 Java Lock 同步锁
			前言 Java 的锁实现,有 Synchronized 和 Lock.上一篇文章深入分析了 Synchronized 的实现原理:由Java 15废弃偏向锁,谈谈Java Synchronized 的 ... 
- 巨经典论文!推荐系统经典模型Wide & Deep
			今天我们剖析的也是推荐领域的经典论文,叫做Wide & Deep Learning for Recommender Systems.它发表于2016年,作者是Google App Store的 ... 
- C++编程指南续(10-11)
			十.类的继承与组合 对象(Object)是类(Class)的一个实例(Instance).如果将对象比作房子,那么类就是房子的设计图纸.所以面向对象设计的重点是类的设计,而不是对象的设计. 对于C++ ... 
- 题解 P5401 [CTS2019]珍珠
			蒟蒻语 这题太玄学了,蒟蒻写篇题解来让之后复习 = = 蒟蒻解 假设第 \(i\) 个颜色有 \(cnt_i\) 个珍珠. \(\sum\limits_{i=1}^{n} \left\lfloor\f ... 
- apidoc学习(接口文档定义取代word)
			apidoc的安装,参考:https://blog.csdn.net/qq_36386771/article/details/82149848 生产文档,需要先编写一个apidoc.json对接口文档 ... 
