所以我们最近介绍了Singleton Pattern,我发现它有很多很好的用途,但是只有一个非常小的东西让我烦恼。我注意到在我看到的单例模式的每个例子中,标准的getInstance()方法如下所示:
private static Singleton instance = null;
public static Singleton getInstance() {
if ( instance == null )
instance = new Singleton();
return instance;
}
我想知道的是,检查实例变量是否为空是否有意义?
如果你刚刚将实例变量直接分配给一个新的Singleton实例并且只是像这样返回它,它会工作吗?
private static Singleton instance = new Singleton();
public static Singleton getInstance() {
return instance;
}
很抱歉,如果这似乎浪费了一个问题的时间,但我只是想知道为什么第一个例子在任何地方都有用的原因。
感谢您的时间。
编辑:忘记将方法设为静态。
答案 0 :(得分:2)
两者都是创建Singleton实例的有效方法。前者称为延迟初始化,后者称为急切初始化
如果创建单例实例的成本高,则延迟初始化将有所帮助。在这种情况下,仅在需要时才创建单例实例。
另一方面,急切初始化默认为线程安全
答案 1 :(得分:2)
第1个示例(延迟加载)非线程安全;使它线程安全你可以把它
private static volatile Singleton instance = null;
private static final Object syncObj = new syncObj();
public static Singleton getInstance() { // <- do not forget "static"
// Double checked locking pattern
if (instance != null)
return instance;
synchronize(syncObj) {
if (instance != null)
return instance;
instance = new Singleton();
}
return instance;
}
第二个示例(急切负载)线程安全:
// "final" looks good here
private static final Singleton instance = new Singleton();
public static Singleton getInstance() { // <- do not forget "static"
return instance;
}
答案 2 :(得分:1)
第一个示例是实例创建的延迟加载,其中对getInstance
方法的第一个请求创建实例。
为避免在第一次方法调用时使用延迟加载创建多个对象(同时从多个线程创建),必须同步对象创建。
if (null == instance ) {
synchronized (Singleton.class){
if (null == instance ) {
instance = new Singleton();
}
}
}
答案 3 :(得分:1)
在第一个示例中,您只在第一次真正需要时(延迟初始化)创建该类的实例。因此,在您需要课程之前,您使用的内存较少。
如果你有很多Singleton,如果你最终不需要它们,你就可以节省内存和时间。