《剑指Offer——名企面试官精讲典型编程题》
作者:何海涛
一、书上原题再现
面试题2:实现Singleton模式
( 注:Singleton 读音:sing够ten 翻译:单例 )
题目:设计一个类,我们只能生成该类的一个实例。
二、涉及的知识点
三、解题过程
/**
* 总共有五个测试用例,分别是:
* 0、懒汉式-单线程(虽说线程不安全,但是真香:节省资源、高效率)
* 1、懒汉式-同步多线程(线程安全,但是不好:节省资源、低效率)
* 2、对懒汉式的优化-同步多线程-双重检测(可行,节省资源,稍高效率)
* 3、饿汉式-天生线程安全(推荐使用,浪费资源、高效率)
* 4、静态内部类-天生线程安全(推荐使用,浪费资源、高效率)
*/
完整解题代码(Java版)
由于完整代码太长,我把他放到了我的GitHub里面了:
四、调试步骤
使用MyEclipse进行调试
下图为懒汉单线程运行50次,一但出现多线程就可能出现多个对象,从而失去单例模式的功能:
(注意我没有说“会”出现,“一定”出现,这样的词,而是委婉的说“可能”出现多个对象)
下图为懒汉双重检测线程运行50次,始终为同一个对象,懒汉式多线程、饿汉式和静态内部类同理:
后来我觉得运行50次太少了,不足以说明问题,我就挨个运行了1500次,下图是我做的一些时间效率记录:
由上图可以看出:
一、 如果不要求线程安全,那么单纯的懒汉模式是真香,即不会提前生成对象占用资源,与不会跑太长时间。
二、 如果要求线程安全,那么推荐使用饿汉模式和静态内部类模式,原因就是既能保证同步又有较高的时间效率。
另外,在JDK源码里,有一个类叫Runtime,它就实现了单例模式,这个类的位置在:
rt.jar->java.lang->Runtime.class
Runtime.class源代码如下:
这个类反正我是从来没有用过,具体用法可以参考博客园huhx的文章《java基础---->Runtime类的使用》:https://www.cnblogs.com/huhx/p/baseusejavaruntime1.html
五、总结
单例模式首先需要知道的是定义,饿汉和懒汉的说法就在于什么时候创建对象,如果在类声明的时候就new对象,那么就是饿汉;如果说忍忍,先声明对象并不new,等类被调用的时候,在静态工厂函数内部生成对象,那么就叫延迟加载对象,即懒汉。
然后就是如何手写出来十几行代码,当然,五种情况都写的话,那就是手写五六十行代码了。
至于实际应用,实际应用就是锻炼思维了,真正代码里面不怎么用。
六、声明与致谢
本题源代码请移步《剑指Offer》作者何海涛的GitHub:https://github.com/zhedahht/CodingInterviewChinese2
参考文章:(每篇文章我都会去点赞,好的文章就应该公诸于世,大家共同学习)
博客园:
Andy.Zhou《你真的会写单列模式吗------Java实现》:https://www.cnblogs.com/andy-zhou/p/5363585.html
CSDN:
Yoda_wang《搞懂设计模式:单例模式》:https://blog.csdn.net/learningcoding/article/details/80471475
炸斯特《java设计模式之单列模式》:https://blog.csdn.net/jason0539/article/details/23297037
Mlinge-奋斗吧《高并发下线程安全的单列模式(最全最经典)》:https://blog.csdn.net/cselmu9/article/details/51366946
孙海友《JDK设计模式之——单列模式(Singleton)》:http://770736680.iteye.com/blog/2035740