这是否正确:
SingletonHolder
运行时才会初始化类Singleton.getInstance()
。这依赖于SingletonHolder
仅在Singleton.getInstance()
内被引用。它的线程安全,因为类加载器负责同步。Singleton
的代码,就会解析其所有静态字段。它也是线程安全的,因为类加载器负责同步。单身持有人。
public class Singleton {
private static class SingletonHolder {
private static final Singleton INSTANCE = new Singleton();
}
public static Singleton getInstance() {
return SingletonHolder.INSTANCE;
}
private Singleton(){ }
}
没有持有人的单身人士。
public class Singleton{
private static final Singleton INSTANCE = new Singleton();
public static Singleton getInstance(){
return INSTANCE;
}
private Singleton(){ }
}
更新以回应@ jan的建议,即这是What is an efficient way to implement a singleton pattern in Java?的副本。我不同意。我不是问最好的方法是什么:我只是问这两个具体实现是什么使得lazy与eager加载相比。像xyz's这样的答案广泛地解决了懒惰与渴望的问题,但不是通过对比我试图检查的两个例子(或者使用相同的关键字,这就是为什么它在我的初始搜索中从未出现过)。
答案 0 :(得分:2)
在回应@Sriram时,这是我的测试,以证明哪个是渴望与延迟加载。
public class Singleton {
private static class SingletonHolder {
static {
System.out.println("In SingletonHolder static block.");
}
private static final Singleton INSTANCE = new Singleton();
}
public static Singleton getInstance() {
System.out.println("In getInstance().");
return SingletonHolder.INSTANCE;
}
private Singleton() {
System.out.println("In constructor.");
}
private void doSomething() {
System.out.println("Singleton working.");
}
public static void main(String[] args) {
System.out.println("Start of main.");
Singleton.getInstance().doSomething();
System.out.println("End of main.");
}
}
输出显示main
方法在调用getInstance()
之前启动,因此延迟加载。
Start of main.
In getInstance().
In SingletonHolder static block.
In constructor.
Singleton working.
End of main.
public class Singleton {
static {
System.out.println("In Singleton static block.");
}
private static final Singleton INSTANCE = new Singleton();
public static Singleton getInstance() {
System.out.println("In getInstance().");
return INSTANCE;
}
private Singleton() {
System.out.println("In constructor.");
}
private void doSomething() {
System.out.println("Singleton working.");
}
public static void main(String[] args) {
System.out.println("Start of main.");
Singleton.getInstance().doSomething();
System.out.println("End of main.");
}
}
输出显示main
方法在调用getInstance()
方法后启动,因此急切地加载。
In Singleton static block.
In constructor.
Start of main.
In getInstance().
Singleton working.
End of main.