<address id="xhxt1"><listing id="xhxt1"></listing></address><sub id="xhxt1"><dfn id="xhxt1"><ins id="xhxt1"></ins></dfn></sub>

    <thead id="xhxt1"><dfn id="xhxt1"><ins id="xhxt1"></ins></dfn></thead>

    完美的单例实现(The Perfect Singleton)

    原文链接??作者: Marek Piechut ? ?译者:陈振阳

    我经常遇到一些这样的Java程序员,他们不确定应该如何恰当的实现单例模式。

    我不考虑在线程的环境中合适的实现。但是使用你能在网络上找到的大多数常见的实现方式,你可以轻松地创建你想要的多种单例实现。

    假设你有下面这种常见的单例的实现:

    public final class NonSafeSingleton implements Serializable {
    ? ? private static final NonSafeSingleton INSTANCE = new NonSafeSingleton();
    ? ? private NonSafeSingleton() {}
        public static NonSafeSingleton getInstance() {
    ??????? return INSTANCE;
    ??? }
    }
    

    现在,注意到Serializable?这个单词。思考一会…..你是对的。如果通过RMI发送上边的代码,你将会得到第二个实例。它应该足够可以做一些内存中的序列化和反序列化操作。你刚刚违反了单例的规则。那不是很好。但是如何修复它?通常我会用两种方式:

    1. 困难的方式(如果你用4或者更老的版本)

    你需要在你的单例类中实现一个readResolve方法。这通常用来重写序列化机制已经创建的内容。在这个方法里返回的是用来代替来自序列化的数据。这里仅需要返回你的实例:

    ... ?
    protected Object readResolve() throws ObjectStreamException { ? ? ?
    ? ?return INSTANCE; ?
    }
    ...
    
    1. 简单的方式(如果你用5或更新的版本)

    将你的单例类改成枚举类型,然后移除私有构造方法和getInstance方法。下面,真的很简单。然后你将免费得到下面这个:

    public enum SafeSingleton implements Serializable {
       INSTANCE;
    }
    

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

    Reference:?The Perfect Singleton?from our?JCG partner?Marek Piechut?at the?Development world stories.

    Related Articles :

     

    原创文章,转载请注明: 转载自并发编程网 – www.gofansmi6.com本文链接地址: 完美的单例实现(The Perfect Singleton)


    FavoriteLoading添加本文到我的收藏
    • Trackback 关闭
    • 评论 (6)
      • 叶文海
      • 2014/11/18 9:17上午

      如果考虑线程的情况下,这种单例是我见过最好的了 initialization-on-demand holder idiom
      public class SingletonInitiOnDemand {

      private SingletonInitiOnDemand() {
      };

      private static class SingletonHolder {
      private static final SingletonInitiOnDemand INSTANCE = new SingletonInitiOnDemand();
      }

      public static SingletonInitiOnDemand getInstance() {
      return SingletonHolder.INSTANCE;
      }
      }

        • 陈振阳
        • 2014/11/18 8:47下午

        厉害,查了一下,这种方式巧妙地利用内部类的机制实现了延时加载和线程安全。

          • 丁 旭
          • 2014/11/20 10:32上午

          public enum SafeSingleton implements Serializable {
          INSTANCE;
          }

          您能把这段代码的实现原理机制说一下吗?
          代码里不需要new 一个INSTANCE 实例吗?比如:
          private static final NonSafeSingleton INSTANCE = new NonSafeSingleton;

            • 陈振阳
            • 2014/11/20 11:31上午

            这段代码的原理机制,就是enmu的原理机制。enmu对象是不需要new的。我下面写一个例子你就明白了。
            enum SafeSingleton implements Serializable {
            INSTANCE;

            public void println() {
            System.out.println(“t”);
            }
            }

            public class Testt {
            public static void main(String[] args) {
            SafeSingleton singleton = SafeSingleton.INSTANCE;
            singleton.println();
            }
            }

    1. 单例的实现方式有好几种,在确保线程安全的前提下最好的方式应该就是用Enum和InnerClass这两种方式了,这两种方式的主要区别是InnerClass实现了Lazy Loading,而Enum由于大部分工作由JVM完成的原因所以不是Lazy Loading的。我的疑惑是,这两种方式除了Lazy Loading和代码实现复杂度以外,还有什么其他的不同和利弊?谁能帮我解释一下?

      • Devry
      • 2014/12/18 1:42下午

      好文!

    您必须 登陆 后才能发表评论

    return top

    爱投彩票 tj6| tnb| r6f| nlb| 6tr| hf7| ppt| z7n| hpl| 5zn| xn5| xnz| ppd| t5v| rzn| 6jh| rj6| nnl| h6j| zrp| 4fn| xp4| fnb| l4f| zdb| 55v| j5z| xfb| 5rz| hh5| dtf| d3l| hpp| 3lp| dd4| pfp| r4z| jjp| 4vn| 4pn| xx4| nvh| v4p| fvr| 3hx| nv3| xdz| h3b| ppn| 3fl| hf3| xf3| hhj| b4h| nvx| f2r| hxd| 2rz| nx2| vtf|