《剑指offer》002-实现Singleton模式(java实现)
来源:互联网 发布:大数据挖掘与应用 编辑:程序博客网 时间:2024/06/05 03:37
题目:设计一个类,只能生成该类的一个实例
《剑指offer》上为C#版本,并查阅网上大神的答案,稍作整理,有些不懂的地方供以后慢慢学习。
先贴出面试时代码,原理及思路在四:
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
单例模式的应用场景:
在计算机系统中,线程池、缓存、日志对象、对话框、打印机、显卡的驱动程序对象常被设计成单例。这些应用都或多或少具有资源管理器的功能。每台计算机可以有若干个打印机,但只能有一个Printer Spooler(打印后台处理服务),以避免两个打印作业同时输出到打印机中。每台计算机可以有若干通信端口,系统应当集中管理这些通信端口,以避免一个通信端口同时被两个请求同时调用。
一、加载类时就初始化此实例
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
这就是传说中的饿汉模式,比较简单,不存在多线程同步问题,避免了synchronized所造成的性能问题;当类Singleton被加载时,会初始化static的instance,并分配内存空间,从这以后,这个static的instance对象便一直占着这段内存(即便你还没有用到这个实例),当类被卸载时,静态变量被摧毁,并释放所占有的内存,因此在某些特定条件下会耗费内存。
二、使用懒加载
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
这就是饱汉式,比较简单,当类SingletonTest被加载的时候,static的instance未被创建(就没分配内存啦),当getInstance方法第一次被调用时,初始化instance变量并分配内存,因此在某些特定条件下会节约了内存;但是并发环境下可能出现多次调用getInstance(),初始化多个SingletonTest实例。
三、考虑多线程(常用)
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
使用synchronized关键字避免多线程访问时出现多个Singleton实例;同步方法频繁调用时,效率略低。
四、考虑性能
//面试时用这个版本就对了
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
此为线程安全且效率比较高的版本。
synchronized关键字修饰getInstance()方法,会导致所有调用getInstance()方法的线程都要竞争同一把锁,即使在单例对象已经生成好的情况下。这里使用double check的方式。(即先判断是否为null,为空的话就竞争锁,不为空就直接返回Instance)。另外,还需要注意instance在初始化过程中,可能已经不为null,这样有可能会导致程序崩溃,因此这里加了个临时变量t,确保初始化完成之后再赋值给instance。(这里的t的作用和上面的volatile的作用是一样的,两者使用一个就可以了)
由于Java会对指令进行重排序,因此有可能会出现instance不为null,但是构造函数还没有执行完的情况,这时如果使用这个对象就有可能出现不可预期的情况,崩溃是一种可能。
五、更简单的方法
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
内部定义一个私有类型NestedClass,当第一次用到这个嵌套类型的时候,会调用静态构造函数创建Singleton实例instance。类型NestedClass只在Singleton.getInstance()中用到,由于其private属性他人无法使用NestedClass类型。因此当第一次通过Singleton.getInstance()得到Singleton的实例时,就会调用NestedClass的构造函数创建instance,如果不调用Singleton.getInstance()就不会触发调用NestedClass,就不会创建实例这样就做到按需创建,提高空间使用效率。
思路及总结:
单例模式要求在系统运行时,存在唯一的实例对象。
“存在唯一”,首先考虑到静态变量,但此处是实例对象,所以先试试在类内部创建一个该类的成员变量,或者可以考虑下静态内部类。
Java中单例模式定义:“一个类有且仅有一个实例,并且自行实例化向整个系统提供。”
如何保证一个类只有一个实例并且这个实例易于被访问呢?定义一个全局变量可以确保对象随时都可以被访问,但不能防止我们实例化多个对象。一个更好的解决办法是让类自身负责保存它的唯一实例。这个类可以保证没有其他实例被创建,并且它可以提供一个访问该实例的方法。
显然单例模式的要点有三个;一是某个类只能有一个实例;二是它必须自行创建这个实例;三是它必须自行向整个系统提供这个实例。
从具体实现角度来说,就是以下三点:一是单例模式的类只提供私有的构造函数,二是类定义中含有一个该类的静态私有对象,三是该类提供了一个静态的公有的函数用于创建或获取它本身的静态私有对象。
参考:http://www.cnblogs.com/yinxiaoqiexuxing/p/5605338.html
以下值得注意:
事实上,可以通过Java反射机制来实例化private类型的构造方法,此时基本上会使所有的Java单例实现失效。
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
如有不懂还可以参考http://www.iteye.com/topic/652440
和http://www.cs.umd.edu/~pugh/java/memoryModel/DoubleCheckedLocking.html。
- 《剑指offer》002-实现Singleton模式(java实现)
- 剑指offer---实现Singleton模式(2)
- 剑指offer - 实现Singleton模式
- 【剑指offer Java】面试题2:实现Singleton模式
- 剑指offer面试题2—实现Singleton模式(Java实现)
- 剑指offer(1) - 实现Singleton模式
- 剑指Offer系列---(4)实现Singleton模式
- 剑指offer 2. 实现Singleton模式
- 剑指offer(1):实现Singleton单例模式
- 剑指offer面试题2:实现Singleton模式(Java版)
- 剑指offer面试题2:实现Singleton模式(Java版)
- 剑指Offer算法实现之二:实现Singleton模式
- 剑指offer面试题 java实现版 面试题2 实现Singleton模式
- 剑指Offer:面试题2 实现Singleton模式
- 剑指offer之实现Singleton(单例)模式
- 剑指Offer----面试题二:实现Singleton模式
- 剑指offer 面试题2 Singleton模式 C++实现
- 剑指offer|面试题2:实现Singleton模式
- spring、springMVC简单应用FutureTask(线程池)
- Git常用命令
- ¥¥%%%%%Ubuntu下用matplotlib作图时显示中文###重点第5条可以用!!!!%%%%%
- 系统还原点
- VmWare 安装XP系统 出现未找到硬盘驱动器的错误
- 《剑指offer》002-实现Singleton模式(java实现)
- SDK manager打不开解决办法
- workbench 数据库设计
- 直流斩波电路---DC Chopper
- 【MySQL-性能优化2】 开启慢查日志的方式和存储格式
- 剑指offer:用两个栈实现队列
- Oracle 11G 安装图解
- HBase中的HMaster、HRegionServer、Zookeeper
- Unity CustomFont (怎么制作图片文字)