Java 单例模式推荐方法
案例1: 案例2:Java 单例模式推荐方法,java,design-patterns,singleton,Java,Design Patterns,Singleton,案例1: 案例2: public class Singleton { public static final Singleton INSTANCE = new Singleton(); private Singleton() { ... } } 第二种方法是实现Singleton设计模式的推荐方法吗,因为我在任何Singleton模式的示例中都没有见过第一种方法。创建Singleton的最佳方法是使用Enum public class Singleton { pr
public class Singleton {
public static final Singleton INSTANCE = new Singleton();
private Singleton() {
...
}
}
第二种方法是实现Singleton设计模式的推荐方法吗,因为我在任何Singleton模式的示例中都没有见过第一种方法。创建Singleton的最佳方法是使用Enum
public class Singleton {
private static final Singleton INSTANCE = new Singleton();
private Singleton() {
...
}
public static Singleton getInstance() {
return INSTANCE;
}
}
在不讨论单例作为反模式的所有内容的情况下(但您应该仔细阅读!),目前在Java中创建单例的最佳方法是使用枚举
public enum Foo {
INSTANCE;
}
这样做更好的原因是JVM保证在任何时候都只存在一个枚举实例(每个类加载器)。它是线程安全的,并且不能使用反射来创建singleton的另一个实例
枚举值也是惰性实例化的,因此在第一次访问
singleton.INSTANCE
之前不会创建singleton。是的,显然第二种方法是实现Sigleton模式的首选方法,在getInstance()内您必须检查实例是否已创建,然后返回相同的实例,并且只有在没有该类的实例时才创建新实例
还将getInstance方法设置为静态方法 在您的示例中,案例1更简单,因此更好。 但是想知道如果你的构造函数更复杂,有一些参数会发生什么。此时,你真的需要这样的东西:
public enum Singleton {
INSTANCE;
}
创建Singleton对象的第一个过程甚至在使用Singleton类之前就创建了该类的实例,这不是最好的使用方法 在第二次实现中也存在同样的问题。 我首选的单例实例创建方式:
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;
}
}
上述单线程实例创建的实现在单线程环境中是可以的,但在多线程环境中,两个线程可能同时访问if块,所以它们将具有不同的实例。这可以通过以下方式解决:
private static final Singleton INSTANCE = null;
public static Singleton getInstance(){
if(INSTANCE == null)
INSTANCE = new Singleton();
return INSTANCE;
}
希望这有帮助。这是我如何用enum实现单例的
private static final Singleton INSTANCE = null;
public static Singleton getInstance(){
if(INSTANCE == null){
synchronized (Singleton.class) {
if(INSTANCE == null){
INSTANCE = new Singleton();
}
}
}
return INSTANCE;
}
我只是指静态的。没有真正的区别。getter对于延迟实例化可能很有用,但是您没有这样做(除了类加载器已经做的事情)。我认为懒惰和渴望仍然是唯一的区别。谢谢(除非还有一些我们忽略的差异)否:建议使用枚举方法,但如果应用程序受益于延迟加载,你还会推荐使用enum吗?你能详细解释一下为什么它比上述两种方法好吗?当对象实例化变得更复杂时,你还必须使用获取它的方法。您的示例很简单,因为它调用默认构造函数。设想一个场景,在这个场景中,您的单例对象必须通过工厂模式获取。是的,所以我建议您使用方法getInstance,而不是构造函数方式。当您使用工厂模式时,GetInstance将起作用。不知道枚举值是惰性实例化的。谢谢你的信息!
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()