我正在阅读关于Singleton设计模式和评估不同实现的文章。我对以下实现有疑问:
A.静态内部类的单例实现
public class SingletonWithStaticClass {
private SingletonWithStaticClass(){}
private static class SingletonInnerClass{
public static SingletonWithStaticClass INSTANCE = new SingletonWithStaticClass();
}
public static SingletonWithStaticClass getInstance(){
return SingletonInnerClass.INSTANCE;
}}
B.单点双检查锁定
public class SingletonWithDoubleCheck {
private static SingletonWithDoubleCheck INSTANCE = null;
private SingletonWithDoubleCheck(){
if(INSTANCE != null){
throw new RuntimeException("Accessing private constructor is prohibited. Use getInstance method instead");
}
}
public static SingletonWithDoubleCheck getInstance(){
if(INSTANCE == null){
synchronized (SingletonWithDoubleCheck.class) {
if(INSTANCE == null){
INSTANCE = new SingletonWithDoubleCheck();
}
}
}
return INSTANCE;
}}
哪一个更好?
我觉得我们可以在第一个实现中访问具有反射的私有构造函数,因为第二个实现是安全的(不受反射攻击)。
但是,我不会在我的生产代码中使用任何这些,我将使用enum。但是在这两种攻击中,第一种实现不是在被认为是反射攻击时被破坏了吗?
如果我的理解有误,请纠正我。
发布于 2015-12-29 14:17:07
两者都太复杂了。第一个选项是Java5.0之前的最佳选项,但第二个选项从来不是一个好选择。它在Java5.0之前没有工作,它需要一个volatile字段,在这个版本之后,您可以使用enum
我更喜欢使用enum来定义一个只有一个实例的类。它是一个final类,线程安全,延迟加载,并且有一个private构造函数。
enum Singleon {
INSTANCE;
}只有当您必须在其构造中提供配置信息时,双锁单例才是有用的。在这种情况下,我更喜欢使用依赖注入来提供/配置单例,并且只有不需要配置的无状态单例。
发布于 2015-12-29 14:21:32
两者都不是好的--而试图用不同的尺度对它们进行比较是适得其反的。
第一种是不必要的复杂,就像你说的,对反射黑客是开放的,但另一种也是如此,只是稍微不那么复杂。
第二种方法是使用synchronized,这是伴随成本的。
https://stackoverflow.com/questions/34512725
复制相似问题