Singleton模式结合了延迟加载和线程安全性

tun*_*fdg 24 java singleton design-patterns

我正在做一些关于单身人士的研究,特别是关于单身人士的懒惰与急切初始化.

急切初始化的一个例子:

public class Singleton
{
    //initialzed during class loading
    private static final Singleton INSTANCE = new Singleton();

    //to prevent creating another instance of Singleton
    private Singleton(){}

    public static Singleton getSingleton(){
        return INSTANCE;
    }
}
Run Code Online (Sandbox Code Playgroud)

但如上所示,它是急切的初始化和线程安全留给jvm但现在,我希望有相同的模式,但延迟初始化.

所以我想出了这个方法:

public final class Foo {
    private static class FooLoader {
        private static final Foo INSTANCE = new Foo();
    }
    private Foo() {
        if (FooLoader.INSTANCE != null) {
            throw new IllegalStateException("Already instantiated");
        }
    }
    public static Foo getInstance() {
        return FooLoader.INSTANCE;
    }
}
Run Code Online (Sandbox Code Playgroud)

如上图所示

private static final Foo INSTANCE = new Foo(); 
Run Code Online (Sandbox Code Playgroud)

只有在实际使用类FooLoader时才会执行,这会处理惰性实例化,并保证它是线程安全的.

它是否正确?

Joh*_*int 21

在我看来,你的第二个代码片段是线程安全的懒惰初始化单例的最佳方式.它实际上有一个模式名称

初始化按需持有人习语

我建议你使用它.


Zho*_*gYu 6

你第一次设计实际上是懒惰的.想一想,实例只在初始化类时创建; 只在getSingleton()调用方法[1] 时才初始化类.因此,实例仅在被要求时创建,即它是懒惰创建的.

[1] http://docs.oracle.com/javase/specs/jls/se7/html/jls-12.html#jls-12.4.1

  • 但它不可能包含公共静态字段:) (2认同)