java单例实例化

jur*_*iks 9 java singleton instance

我已经找到了三种实例化Singleton的方法,但我怀疑它们中是否有最好的方法.我在多线程环境中使用它们并且更喜欢惰性实例化.
样本1:

private static final ClassName INSTANCE = new ClassName();

public static ClassName getInstance() {
    return INSTANCE;
}
Run Code Online (Sandbox Code Playgroud)

样本2:

private static class SingletonHolder { 
    public static final ClassName INSTANCE = new ClassName();
}

public static ClassName getInstance() {
    return SingletonHolder.INSTANCE;
}
Run Code Online (Sandbox Code Playgroud)

样本3:

private static ClassName INSTANCE;

public static synchronized ClassName getInstance()
{
    if (INSTANCE == null)
        INSTANCE = new ClassName();

    return INSTANCE;
}
Run Code Online (Sandbox Code Playgroud)

我正在使用ATM的项目到处都使用Sample 2,但我更喜欢Sample 3.还有Enum版本,但我只是不明白.

这里的问题是 - 在哪些情况下我应该/不应该使用这些变化中的任何一种?我不是在寻找冗长的解释(关于这一点还有很多其他主题,但它们最终都变成了争论IMO),我希望用几句话来理解它.

Boz*_*zho 20

在java中实现单例的最安全和最简单的方法是使用枚举(如你所提到的):

public enum ClassName {
    INSTANCE;

    // fields, setters and getters
}
Run Code Online (Sandbox Code Playgroud)

枚举语义保证只有一个 INSTANCE

如果不使用枚举方法,你必须处理很多方面,比如竞争条件和反射.我一直在打破一些框架的单例,并滥用它们,因为它们没有正确编写.枚举保证没有人会破坏它.


dog*_*ane 5

示例 1 不使用延迟初始化。

示例 2 和 3 都是惰性的。样品2使用了初始化点播支架成语(IODH) ,其具有不同步开销。因此它比示例 3 更快。

在 Effective Java(第 3 条)中,Joshua Bloch 建议单元素枚举类型是实现单例的最佳方式

但是,如果您不确定枚举类型,请坚持使用 IODH。