首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >具有静态内部类和双重检查锁定的Singleton

具有静态内部类和双重检查锁定的Singleton
EN

Stack Overflow用户
提问于 2015-12-29 14:06:08
回答 2查看 1.1K关注 0票数 4

我正在阅读关于Singleton设计模式和评估不同实现的文章。我对以下实现有疑问:

A.静态内部类的单例实现

代码语言:javascript
运行
复制
public class SingletonWithStaticClass {

private SingletonWithStaticClass(){}

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

}

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

}

B.单点双检查锁定

代码语言:javascript
运行
复制
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。但是在这两种攻击中,第一种实现不是在被认为是反射攻击时被破坏了吗?

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

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2015-12-29 14:17:07

两者都太复杂了。第一个选项是Java5.0之前的最佳选项,但第二个选项从来不是一个好选择。它在Java5.0之前没有工作,它需要一个volatile字段,在这个版本之后,您可以使用enum

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

代码语言:javascript
运行
复制
enum Singleon {
    INSTANCE;
}

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

票数 6
EN

Stack Overflow用户

发布于 2015-12-29 14:21:32

两者都不是好的--而试图用不同的尺度对它们进行比较是适得其反的。

第一种是不必要的复杂,就像你说的,对反射黑客是开放的,但另一种也是如此,只是稍微不那么复杂。

第二种方法是使用synchronized,这是伴随成本的。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/34512725

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档