它是否正确:
- Using a 带支架的单例给出延迟初始化,因为该类
SingletonHolder
仅在以下情况下初始化Singleton.getInstance()
正在运行。这依赖于SingletonHolder
仅在内部被引用Singleton.getInstance()
。它是线程安全的,因为类加载器负责同步。
- 使用没有持有者的单例是急切的初始化,因为一旦 Java 遇到引用的代码
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(){ }
}
Update回应@jan的建议,这是重复的在 Java 中实现单例模式的有效方法是什么?。我不同意。我不是问最好的方法是什么:我只是问是什么让这两个特定的实现延迟加载与急切加载。答案如xyz's广泛地解决懒惰与渴望的问题,但不是通过对比我试图检查的两个示例(或使用相同的关键字,这就是为什么它从未出现在我的初始搜索中)。
为了回应@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
方法开始after the getInstance()
方法被调用,因此被急切地加载。
In Singleton static block.
In constructor.
Start of main.
In getInstance().
Singleton working.
End of main.
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)