单例模式推荐方法

时间:2016-11-29 10:04:39

标签: java design-patterns singleton

案例1:

public class Singleton {

  public static final Singleton INSTANCE = new Singleton();

  private Singleton() {
    ...
  }
}

案例2:

public class Singleton {

  private static final Singleton INSTANCE = new Singleton();

  private Singleton() {
    ...
  }

  public static Singleton getInstance() {
    return INSTANCE;
  }
}

第二种方法是实现Singleton设计模式的推荐方法,因为我从未在Singleton模式的任何示例中看到过第一种方法。

6 个答案:

答案 0 :(得分:3)

没有涉及作为反模式的单身人士的所有内容(但你应该阅读它!),目前在Java中制作单例的最佳方法是使用枚举。

public enum Singleton {
    INSTANCE;
}

这更好的原因是因为JVM保证在任何时候只存在一个枚举实例(每个类加载器)。它是线程安全的,你不能使用反射来创建单例的另一个实例。

枚举值也会被懒惰地实例化,所以在第一次访问Singleton.INSTANCE之前,你不会创建单例。

答案 1 :(得分:1)

制作单身人士的最佳方法是使用Enum。

public enum Foo {
    INSTANCE;
}

What is an efficient way to implement a singleton pattern in Java?

答案 2 :(得分:0)

在您的示例中,案例1更简单,因此更好。 但是想知道如果你的构造函数对某些参数更复杂会发生什么。在这个时候,你真的需要这样的东西:

public class Singleton {

 private static final Singleton INSTANCE;

 private Singleton(string a, string b, string c) {
   ...
 }

public static Singleton getInstance(string a, string b, string c) {
   if (INSTANCE != null) { //note in multiple thread env, need add synchronize here.
       ......
   }
   return INSTANCE;
}
}

答案 3 :(得分:0)

创建Singleton对象的第一个过程甚至在使用之前就创建了Singleton类的实例,这不是最佳实践。

第二种实现中也存在同样的问题。 我首选的单例实例创建方法:

 private static final Singleton INSTANCE = null;
 public static Singleton getInstance(){
      if(INSTANCE == null)
        INSTANCE = new Singleton();
    return INSTANCE;
 }

单线程实例创建的上述实现在单线程环境中是可以的,但是在多线程环境的情况下,两个线程可以同时访问块,因此它们将具有不同的实例。这可以解决如下:

private static final Singleton INSTANCE = null;
 public static Singleton getInstance(){
    if(INSTANCE == null){
        synchronized (Singleton.class) {
            if(INSTANCE == null){
                INSTANCE = new Singleton();
            }
        }
    }
    return INSTANCE;
 }

希望这有帮助。

答案 4 :(得分:0)

这是我如何使用枚举实现单例

import static collections.concurrancy.ConcurrentHashMapInstanceEnum.STAFF;
public enum ConcurrentHashMapInstanceEnum {
    STAFF;
    private ConcurrentHashMap<Integer,Person> concurrentHashMap = null;

    private ConcurrentHashMapInstanceEnum() {
            concurrentHashMap = new ConcurrentHashMap(10, 5f, 4);
    }

    public ConcurrentHashMap getConcurrentHashMap() {
        return concurrentHashMap;
    }
}    

这就是如何在一个线程中达到......

 staffList = STAFF.getConcurrentHashMap()

答案 5 :(得分:-1)

是显然第二种方法是实现Sigleton模式的首选方法,在getInstance()内部,您必须检查实例是否已经创建然后返回相同的内容,如果没有该类的实例,则只创建新实例。

还将getInstance方法设为静态方法。