ITPub博客

首页 > 应用开发 > Java > 单例与序列化

单例与序列化

Java 作者:541732025 时间:2014-12-03 22:15:31 0 删除 编辑
【转载】原文见http://ifeve.com/perfect-singleton/

原文的题目叫“完美的单例实现”,但是看了下内容,不敢苟同,就我所知,要写一个安全、完美的单例是要考虑很多方面的,譬如懒加载、并发问题、内存模型、指令重排等。
但是原文中并有提及到这些,仅仅说了一下序列化与单例,所以这里我就叫“单例与序列化”吧。
我经常遇到一些这样的Java程序员,他们不确定应该如何恰当的实现单例模式。
我不考虑在线程的环境中合适的实现。但是使用你能在网络上找到的大多数常见的实现方式,你可以轻松地创建你想要的多种单例实现。
假设你有下面这种常见的单例的实现:
public final class NonSafeSingleton implements Serializable {
    private static final NonSafeSingleton INSTANCE = new NonSafeSinglet
    private NonSafeSingleton() {}
    public static NonSafeSingleton getInstance(){
        return INSTANCE;    
    }    
}


现在,注意到Serializable 这个单词。思考一会…..你是对的。如果通过RMI发送上边的代码,你将会得到第二个实例。它应该足够可以做一些内存中的序列化和反序列化操作。
你刚刚违反了单例的规则。那不是很好。但是如何修复它?通常我会用两种方式:
1,困难的方式(如果你用4或者更老的版本)
你需要在你的单例类中实现一个readResolve方法。这通常用来重写序列化机制已经创建的内容。在这个方法里返回的是用来代替来自序列化的数据。这里仅需要返回你的实例:
...  
protected Object readResolve() throws ObjectStreamException {      
   return INSTANCE;  
}
...

2,简单的方式(如果你用5或更新的版本)
将你的单例类改成枚举类型,然后移除私有构造方法和getInstance方法。下面,真的很简单。然后你将免费得到下面这个:
public enum SafeSingleton implements Serializable {
   INSTANCE;
}

当你再实现单例模式时,记住这些。如果你大量的使用RMI,它可以使你的生活更加简单。

来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/28912557/viewspace-1355780/ ,如需转载,请注明出处,否则将追究法律责任。

请登录后发表评论 登录
全部评论

注册时间:2013-05-23

  • 博文量
    127
  • 访问量
    515714