案例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模式的任何示例中看到过第一种方法。
答案 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方法设为静态方法。