这里的一个最近的问题有以下代码(嗯,类似于这个)来实现一个没有同步的单例。
public class Singleton {
private Singleton() {}
private static class SingletonHolder {
private static final Singleton INSTANCE = new Singleton();
}
public static Singleton getInstance() {
return SingletonHolder.INSTANCE;
}
}
现在,我想明白这是在做什么。由于实例是static final
,它是在任何线程调用之前很久就构建的,getInstance()
因此不需要同步。
仅当两个线程尝试同时调用时才需要同步getInstance()
(并且该方法在第一次调用而不是"static final"
同时进行构造)。
因此,我的问题基本上是:为什么你会更喜欢单例的惰性构造,例如:
public class Singleton {
private Singleton() {}
private static Singleton instance = null;
public static synchronized Singleton getInstance() {
if (instance == null)
instance = new Singleton();
return instance;
}
}
我唯一的想法是,使用该static final
方法可能会引入排序问题,就像 C++ 静态初始化顺序惨败一样。
首先,Java真的有这个问题吗?我知道类中的顺序是完全指定的,但它是否以某种方式保证类之间的顺序一致(例如使用类加载器)?
其次,如果顺序是一致的,为什么惰性构造选项会有优势?