关于辛格尔顿的事情

时间:2014-03-10 11:27:35

标签: java singleton instance

所以我们最近介绍了Singleton Pattern,我发现它有很多很好的用途,但是只有一个非常小的东西让我烦恼。我注意到在我看到的单例模式的每个例子中,标准的getInstance()方法如下所示:

    private static Singleton instance = null;

    public static Singleton getInstance() {
    if ( instance == null ) 
        instance = new Singleton();
    return instance;
}

我想知道的是,检查实例变量是否为空是否有意义?

如果你刚刚将实例变量直接分配给一个新的Singleton实例并且只是像这样返回它,它会工作吗?

    private static Singleton instance = new Singleton();

    public static Singleton getInstance() {
    return instance;
}

很抱歉,如果这似乎浪费了一个问题的时间,但我只是想知道为什么第一个例子在任何地方都有用的原因。

感谢您的时间。

编辑:忘记将方法设为静态。

4 个答案:

答案 0 :(得分:2)

两者都是创建Singleton实例的有效方法。前者称为延迟初始化,后者称为急切初始化

如果创建单例实例的成本,则延迟初始化将有所帮助。在这种情况下,仅在需要时才创建单例实例。

另一方面,急切初始化默认为线程安全

答案 1 :(得分:2)

第1个示例(延迟加载非线程安全;使它线程安全你可以把它

    private static volatile Singleton instance = null;
    private static final Object syncObj = new syncObj();

    public static Singleton getInstance() { // <- do not forget "static"
      // Double checked locking pattern
      if (instance != null) 
        return instance;

      synchronize(syncObj)  {
        if (instance != null) 
          return instance;

        instance = new Singleton();
      }

      return instance;
   }

第二个示例(急切负载线程安全

  // "final" looks good here
  private static final Singleton instance = new Singleton();

  public static Singleton getInstance() { // <- do not forget "static"
    return instance;
  }

答案 2 :(得分:1)

第一个示例是实例创建的延迟加载,其中对getInstance方法的第一个请求创建实例。

为避免在第一次方法调用时使用延迟加载创建多个对象(同时从多个线程创建),必须同步对象创建。

if (null == instance ) {
    synchronized (Singleton.class){
        if (null == instance ) {
            instance = new Singleton();
        }
    }
}

答案 3 :(得分:1)

在第一个示例中,您只在第一次真正需要时(延迟初始化)创建该类的实例。因此,在您需要课程之前,您使用的内存较少。

如果你有很多Singleton,如果你最终不需要它们,你就可以节省内存和时间。