简体   繁体   English

具有静态内部类和双重检查锁定的单例

[英]Singleton with static inner class and double-checked locking

I am reading about Singleton design pattern and evaluating different implementations. 我正在阅读关于Singleton设计模式和评估不同的实现。 I have doubt with the below implementations: 我怀疑以下的实现:

A. Singleton Implementation with static inner class A.使用静态内部类的单例实现

public class SingletonWithStaticClass {

private SingletonWithStaticClass(){}

private static class SingletonInnerClass{
    public static SingletonWithStaticClass INSTANCE = new SingletonWithStaticClass();

}

public static SingletonWithStaticClass getInstance(){
    return SingletonInnerClass.INSTANCE;
}

} }

B. Singleton double checked locking B. Singleton双重检查锁定

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;
}

} }

Which one is better? 哪一个更好?

I feel we can access the private constructor with Reflection in first implementation where as second implementation is safe (From Reflection attack). 我觉得我们可以在第一个实现中使用Reflection访问私有构造函数,其中第二个实现是安全的(From Reflection攻击)。

However, I am not going to use any of these in my production code, I will use enum instead. 但是,我不打算在我的生产代码中使用任何这些,我将使用枚举 But out of these two, isn't the first implementation is broken when considered Reflection attack? 但是出于这两个,当考虑反射攻击时,是不是第一个实现被破坏?

Please correct me if my understanding is wrong. 如果我的理解是错误的,请纠正我。

Both are overly complicated. 两者都过于复杂。 The first was the best option before Java 5.0, however the second was never a good option. 第一个是Java 5.0之前的最佳选择,但第二个从来都不是一个好选择。 It didn't work before Java 5.0, it requires a volatile field and after this version you could use enum 它在Java 5.0之前不起作用,它需要一个volatile字段,在这个版本之后你可以使用enum

I prefer using an enum to define a class with exactly one instance. 我更喜欢使用enum来定义一个只有一个实例的类。 It is a final class, thread safe, lazy loaded, and has a private constructor. 它是一个final类,线程安全,延迟加载,并有一个private构造函数。

enum Singleon {
    INSTANCE;
}

The double locking singleton is only useful if you must provide configuration information in it's construction. 双锁定单例仅在必须在其构造中提供配置信息时才有用。 In this case, I prefer to use Dependency Injection to provide/configure singletons and only have stateless Singletons which don't require configuration. 在这种情况下,我更喜欢使用依赖注入来提供/配置单例,并且只使用不需要配置的无状态单例。

Neither are good - and attempting to compare them using different scales is counter-productive. 两者都不好 - 并且尝试使用不同的比例来比较它们会适得其反。

The first is unnecessarily complex and, as you say, is open to reflection hacking, but so is the other one, just slightly less so. 第一个是不必要的复杂,正如你所说的那样,反思黑客是开放的,但另一个也是如此,只是稍微不那么重要。

The second uses a synchronized which comes with a cost. 第二个使用带有成本的synchronized

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM