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

标签 java design-patterns 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;
}

哪个更好?

我觉得我们可以在第一个实现中使用反射访问私有(private)构造函数,而第二个实现是安全的(来自反射攻击)。

但是,我不会在我的生产代码中使用任何这些,我将使用 enum 代替。但是在这两个中,当考虑反射攻击时,第一个实现不是被破坏了吗?

如果我的理解有误,请指正。

最佳答案

两者都过于复杂。第一个是 Java 5.0 之前的最佳选择,但是第二个从来都不是一个好的选择。它在 Java 5.0 之前不起作用,它需要一个 volatile 字段,在此版本之后你可以使用 enum

我更喜欢使用 enum 来定义一个只有一个实例的类。它是一个 final 类,线程安全,延迟加载,并且有一个 private 构造函数。

enum Singleon {
    INSTANCE;
}

双重锁定单例仅在您必须在其构造中提供配置信息时才有用。在这种情况下,我更喜欢使用依赖注入(inject)来提供/配置单例,并且只有不需要配置的无状态单例。

关于java - 具有静态内部类和双重检查锁定的单例,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34512725/

相关文章:

java - 以编程方式实现 TestNg 套件并通过 maven surefire 执行它

c# - Singleton 应该是可继承的还是不可继承的?

java - java中Singleton的并发访问

c# - .net 构造/模式按代码段阻塞,而不是按线程阻塞

java - 在类的唯一现有构造函数中创建对 "this"的引用

java - 为什么核心 Java 库不使用枚举来实现单例模式?

java - in.hasNextLine() 在 Java 中永不终止

java - 使用 Struts 2 通配符配置时如何返回 404 错误?

javascript - Singleton 中的公共(public)函数调用自身

java - UML:如何在 Java 中实现关联类