`
coolxing
  • 浏览: 870381 次
  • 性别: Icon_minigender_1
  • 来自: 北京
博客专栏
9a45b66b-c585-3a35-8680-2e466b75e3f8
Java Concurre...
浏览量:96058
社区版块
存档分类
最新评论

实现严谨的singleton类

阅读更多

[coolxing按: 转载请注明作者和出处, 如有谬误, 欢迎在评论中指正.] 

singleton模式是大多数javaer耳熟能详的, 不过要做到真正的单例其实很不容易, 你需要考虑以下问题:

1. 延迟加载时多线程环境下是否能保证单例?

2. 是否可以通过暴力反射获得新的对象?

3. 是否可以通过clone方法获得新的对象?

4. 是否可以通过序列化获得新的对象?

 

对于问题1, 可以通过双重检查加锁解决. 这是运用单例的常识, 不再详细说明.

问题2, 3, 4则是很难避免的.

但是我们可以通过java提供的一种简单的方式创建一个真正的singleton类: 仅有一个实例的枚举类型. 如:

 

public enum Weekday {
	MONDAY;
	private Weekday() {}
}

 

下面我们对这个枚举类进行一一验证.

 

暴力反射

测试代码如下:

public static void main(String[] args) throws Exception {
		Class<?> clazz = Weekday.class;
		Constructor<?> cc = clazz.getDeclaredConstructor(null);
		cc.setAccessible(true);
		cc.newInstance(null);
}

 

运行结果是抛出异常:Exception in thread "main" java.lang.NoSuchMethodException: cn.xing.test.Weekday.<init>()

明明Weekday有一个无参的构造函数, 为何不能通过暴力反射访问?

最新的Java Language Specification (§8.9)规定:  Reflective instantiation of enum types is prohibited. 这是java语言的内置规范.

 

 

clone方法

所有的枚举类都继承自java.lang.Enum类, 而不是Object类. 在java.lang.Enum类中clone方法如下:

protected final Object clone() throws CloneNotSupportedException {
	throw new CloneNotSupportedException();
}

 

调用该方法将抛出异常, 且final意味着子类不能重写clone方法, 所以通过clone方法获取新的对象是不可取的.

 

序列化

java.lang.Enum类的readObject方法如下:

private void readObject(ObjectInputStream in) throws IOException,
        ClassNotFoundException {
            throw new InvalidObjectException("can't deserialize enum");
}

private void readObjectNoData() throws ObjectStreamException {
        throw new InvalidObjectException("can't deserialize enum");
}
 

同暴力反射一样, Java Language Specification (§8.9)有着这样的规定: the special treatment by the serialization mechanism ensures that duplicate instances are never created as a result of deserialization.

 

综上所述, 创建仅有一个实例的枚举类型是实现singleton的最简单, 最严谨的方式.

Java Language Specification下载路径:http://docs.oracle.com/javase/specs/

 

分享到:
评论
1 楼 heipacker 2013-10-06  
这个不错!

相关推荐

    C++ 实现的singleton 模式

    用VC实现的singleton 模式 在VS03,VC6.0下编译通过

    singleton设计模式java实现及对比

    java singleton 不解释不解释不解释不解释

    C++完美实现Singleton模式

    C++完美实现Singleton模式

    Singleton两种代码实现

    单例模式,Singleton两种代码实现。一般实现方法,泛型实现方法(推荐)

    单例实现源码singleton-C++

    实现了单例模型。 vs2015的工程

    C++CLI中实现singleton模式

    在ACE的实现中就大量使用ACE_Singleton模板类将普通类转换成具有Singleton行为的类。这种方式很好地消除了一些重复代码臭味,而且,优化后的性能较标准互斥版本提高15倍。最近在用C++/CLI做一些工作,Singleton不可...

    Laravel开发-singleton-pattern

    Laravel开发-singleton-pattern 帮助程序包来实现单例类。

    C++实现Singleton单例模式

    本文档,是利用C++来实现设计模式中的,单例模式,里面有内容说明和相关实例代码介绍

    Python《剑指offer》算法实现-Singleton

    # Python实现《剑指offer》 部分代码自己添加了一些测试用例, 或者自己添加了一些功能 1. 初级程序员注重算法和数据结构 2. 事先做好准备,对工作有热情 3. 面试过程放松。不要急于写代码,了解清楚所要解决的问题,...

    Python《剑指offer》-实现算法Singleton

    # Python实现《剑指offer》 部分代码自己添加了一些测试用例, 或者自己添加了一些功能 1. 初级程序员注重算法和数据结构 2. 事先做好准备,对工作有热情 3. 面试过程放松。不要急于写代码,了解清楚所要解决的问题,...

    单例模式Singleton(java源码)

    单例类只能有一个实例。 单例类必须自己创建自己的唯一实例。 单例类必须给所有其他对象提供这一实例。 Singleton模式包含的角色只有一个,就是Singleton。Singleton拥有一个私有构造函数,确保用户无法通过new直接...

    C++中实现Singleton的正确方法

    如果某个类管理了系统中的某种资源,那么我们只能创建该类的一个实例,此时用到singleton设计模式(后面为了简化将省略“设计模式”四个字)比较合适了。然而,如果不注意实现方法,很有可能会让我们碰到一些...

    单例极致 singleton C++

    四种常见的单例: 1、没有构造函数(DEFINE_SINGLETON_DEFAULT); 2、有构造函数,构造函数没有参数(DEFINE_SINGLETON_CONSTRUCT_NO_PARAM); 3、有构造函数,构造函数有没有... 通过宏定义巧妙实现,使用也很方便!

    单例模式(Singleton)的6种实现

    单例模式(Singleton)的6种实现,单例模式(Singleton)的6种实现

    Java 单例模式Singleton

    简单的单例模式举例Singleton 分为恶汉式 懒汉式

    Singleton 单例模式的介绍以及解析

    单例模式 Singleton 单例模式线程安全问题和拓展

    Singleton(单例模式)

    1、某些类创建比较频繁,对于一些大型的对象,这可以节省一笔很大的系统开销。 2、省去了new操作符,降低了系统内存的使用频率,减轻GC压力。 3、有些像交易所的核心交易引擎,控制着交易流程,如果该类可以创建多个...

Global site tag (gtag.js) - Google Analytics