什么是正确的单例实现及其原因

时间:2014-03-01 19:29:05

标签: java design-patterns singleton static-members

java中的两个实现有什么区别,哪个是正确的?为什么?

class Singleton
{
    private static Singleton instance = new Singleton();

    private Singleton()
    {
        System.out.println("Singleton(): Initializing Instance");
    }

    public static Singleton getInstance()
    {    
        return instance;
    }

}

或者

class Singleton
{
    private static Singleton instance; 

    static
    {
        instance = new Singleton();
    }  

    private Singleton()
    {
        System.out.println("Singleton(): Initializing Instance");
    }

    public static Singleton getInstance()
    {    
        return instance;
    }


}

6 个答案:

答案 0 :(得分:3)

首先回答你的问题,

AFAIK,两个代码段都相同。我没有看到任何区别。

然而,正如其他答案所示,有更好的方法来创建Singleton实现。但这对你的问题有点偏离主题,互联网(谷歌)是你最好的朋友找到它。

答案 1 :(得分:1)

没有区别。在这两种情况下,您都急切地创建一个实例,并且在调用getInstance()时,实例已准备就绪。

但是如果你正在寻找一个简单而好的单身实现,

最好使用枚举来实现Singleton

public enum Singleton {
       INSTANCE;
   }

答案 2 :(得分:1)

我的回答基于这篇关于单身人士的文章:http://www.cs.umd.edu/~pugh/java/memoryModel/DoubleCheckedLocking.html

  1. 您的第一个示例应始终有效,但不允许延迟初始化。
  2. 在单线程环境中,您可以像“我的”第一个示例一样实现单例。
  3. 在使用Java 1.5和引用的可变对象的多线程环境中,您可以使用“我的”第二个示例。
  4. 有用的stackoverflow答案/文章:
  5. 示例1:

    class SingleSingleton { 
    
        private Helper helper = null;
    
        public Helper getHelper() {
            if (helper == null) 
                helper = new Helper();
            return helper;
        }
    }
    

    示例2:

    class MultiSingletonJDK5 {
        private volatile Helper helper = null;
    
        public Helper getHelper() {
            if (helper == null) {
                synchronized(this) {
                    if (helper == null)
                        helper = new Helper();
                }
            }
            return helper;
        }
    }
    

    我希望这会有所帮助。如果没有,请给我们一些细节或更多背景。

答案 3 :(得分:0)

这两种方法都不是应用Singleton模式的正确方法。

这是正确的方法。 Lazy-Instantiation方式:

public class Singleton
{
  private static Singleton singleton;

  private Singleton()
  {
  }

  public synchronized static Singleton getInstance()
  {
    if (singleton == null)
    {
      singleton = new Singleton();
    }

    return singleton;
  }
}

getInstance()方法在第一次调用时懒惰地实例化Singleton对象。所以Singleton对象在内存中不存在,直到需要它为止。

答案 4 :(得分:0)

两种实现方式都不正确,静态限定符也不是很好的练习:) 有我对Singletns的建议:

public final class LazySingleton {
    private static volatile LazySingleton instance = null;

    // private constructor
    private LazySingleton() {
    }

    public static LazySingleton getInstance() {
        if (instance == null) {
            synchronized (LazySingleton.class) {
                instance = new LazySingleton();
            }
        }
        return instance;
    }
}

public class EagerSingleton {
    private static volatile EagerSingleton instance = null;

    // private constructor
    private EagerSingleton() {
    }

    public static EagerSingleton getInstance() {
        if (instance == null) {
            synchronized (EagerSingleton.class) {
                // Double check
                if (instance == null) {
                    instance = new EagerSingleton();
                }
            }
        }
        return instance;
    }
}

答案 5 :(得分:0)

通常,Singleton设计模式概念基于instance只有classprivate Singleton() { System.out.println("Singleton(): Initializing Instance"); } 。这可以通过两个主要方面达成:

1)为您的类设置一个私有构造函数,以防止任何外部类调用它并重新创建实例。这可以通过以下方式达到:

static

2)使用instance方法,您可以检索已初始化的public static Singleton newInstance() { if (singleton == null) { singleton = new Singleton(); } return singleton; } 或初始化它,如果它尚未初始化为@Awfully在他的回答中提到的很棒:

{{1}}