作者:Balan
什么是Java Singleton
Singleton是独身、单独一个的意思,发音是KK: [
],DJ: [
]。
Java Singleton是指在特定系统范围内只能实例化一次的Java类,并且为该类提供一个全局的访问点。很多地方,Singleton 当作模式来讲。Java Singleton 常用于代表特定系统范围内需要保持唯一性的组件。例如一个蜜蜂王国系统内,蜂王类的实例只能有一个。
实现Java Singleton的方案
Java Singleton是指在特定系统范围内只能实例化一次的Java类,如何理解特定系统范围?按照需求和环境定义系统范围,关注在特定系统范围内单一实例的需求:
系统范围和环境定义
|
方案编号
|
框架容器内 |
A |
单一JVM中、单一类加载器加载类 |
B、C、D |
单一JVM、不同类加载器加载相同类 |
|
系统跨多个JVM |
|
A
提供实例管理容器的第三方框架,例如Spring IOC容器,可以通过配置保证实例在容器内的唯一性。这些被外部容器管理的类,能在某个容器范围内达到Singleton的效果,不一定禁止自身在容器外部范围生成多个实例。 这种方案可以看作是一种局部的单例解决方案。
B
代码示范如下
C
D
有时候类的实例化开销较为昂贵,有时候类的实例化要用到系统运行时的动态数据做参数等等,在上述情形,静态成员变量需要延迟初始化。程序员中间流传较广的一种形式是:
这种写法最大的问题是getInstance()方法被多个线程竞争使用的时候,可能会产生多个实例,违反了单例设计的初衷。如果多个实例的风险(Singleton失败)不会引起您的系统异常,比如实例存放的是无状态的数据、实例是轻量级的,您可以坚持这种写法。
当然还有改进的方法,一般是在该方法前加上“synchronized”关键字:
这种作法的副作用就是影响性能。
双检查锁(Double-Checked Locking)是在多线程环境下实现延迟初始化的有效方式(如C++),不幸的是,对大多数JVM是无效的。有一篇文章解释的很深入:http://www.cs.umd.edu/~pugh/java/memoryModel/DoubleCheckedLocking.html
其他方案
单一JVM、不同类加载器加载相同类或跨多个JVM的情形,要保证Java Singleton不失败,我还没找到恰当的方法。
有些人认为单例的需求不仅仅是来自某些组件自身的唯一特性,还来自对创建并维护多个对象产生消耗的无法忍受、来自对性能的追求。如果出于降低消耗和提高性能的目的,很多无状态的类(类的所有实例天然是始终相同的),即便面临单一JVM、不同类加载器加载相同类或跨多个JVM的情形,也可以采用上述的Singleton实现方式,可以尽量减少实例的数量。
当Java Singleton遇到反序列化
一个序列化的实例,每次反序列化的时候都会产生一个新的实例。Singleton也不例外。
我们看看一个例子:
进行序列化测试
public static void main(String[] args) throws Exception{
//序列化
ObjectOutputStream objectOutputStream = new ObjectOutputStream(new FileOutputStream("E:\\kingBedroom.obj"));
King king_1 = King.INSTANCE;
objectOutputStream.writeObject(king_1);
objectOutputStream.close();
//反序列化
ObjectInputStream objectInputStream = new ObjectInputStream(new FileInputStream("E:\\kingBedroom.obj"));
King king_2 = (King)objectInputStream.readObject();
objectInputStream.close();
//比较是否原来的实例
System.out.println(king_1==king_2);
}
结果是false
解决方法是为King类增加readResolve()方法:
private Object readResolve(){
return INSTANCE;
}
反序列化之后新创建的对象会先调用此方法,该方法返回的对象引用被返回,取代了新创建的对象。本质上,该方法忽略了新建对象,仍然返回类初始化时创建的那个实例。
参考资料:
- “使用私有构造函数强化singleton属性”,《Effective Java中文版
》 Joshua Bloch 著,潘爱民 译
- 深入Java中的Singleton模式与延缓初始化
,dev2dev.bea.com.cn论坛 作者beastiedog_bea
- singleton.zip (5.1 KB)
- 描述: 附件中是本文样例的源代码工程包,使用Eclipse导入即可。
- 下载次数: 76
分享到:
相关推荐
Singleton模式包含的角色只有一个,就是Singleton。Singleton拥有一个私有构造函数,确保用户无法通过new直接实例化它。除此之外,该模式中包含一个静态私有成员变量instance与静态公有方法Instance()。Instance()...
java Singleton单例模式 java Singleton单例模式
简单的单例模式举例Singleton 分为恶汉式 懒汉式
java singleton 不解释不解释不解释不解释
Java的Singleton模式代码(免资源分),你会发现Java的Singleton模式真的很有趣,原来程序还可以这样写。
Java常用设计模式(SingleTon、FactoryMethod、AbstractFactory)
提供简单易懂的单件设计模式源码,为你学习这种模式提供更好捷径.
IOS应用源码——Singleton.rar
Singleton ( 单态模式 ) Builder ( 建造者模式 ) Prototype ( 原型模式 ) Adapter ( 适配器模式 ) Bridge ( 桥接模式 ) Composite ( 组合模式 ) Decorator ( 装饰模式 ) Facade ( 外观模式 ) Flyweight ( 享...
Singleton在Java中的应用,实例介绍
singleton pattern 的定义 主要应用方法 优缺点 通过代码 具体分析解释
Java的几个练习,reflect,singleton,DomAndSax
实现了单例模型。 vs2015的工程
C++完美实现Singleton模式
23种java版设计模式源码案例.zip 0.目录 创建型模式(creational) 简单工厂(simplefactory) 动态工厂(dynamic) 抽象工厂(abstract) 单例模式(singleton) 建造者模式(builder) 原型模式(prototype) 结构型模式...
1、没有构造函数(DEFINE_SINGLETON_DEFAULT); 2、有构造函数,构造函数没有参数(DEFINE_SINGLETON_CONSTRUCT_NO_PARAM); 3、有构造函数,构造函数有没有参数版本(DEFINE_SINGLETON_CONSTRUCT_WITH_DEFAULT)...
文件名 : Singleton1.java 文件名 : Singleton2.java 文件名 : Singleton3.java 文件名 : Singleton4.java 文件名 : Singleton5.java 文件名 : Singleton6.java 文件名 : TestSingleton1.java 文件名 : ...