(来自维基百科)
//延迟初始化:
public class Singleton {
private static volatile Singleton instance = null;
private Singleton() { }
public static Singleton getInstance() {
if (instance == null) {
synchronized (Singleton.class){
if (instance == null) {
instance = new Singleton();
}
}
}
return instance;
}
}
//急切的初始化:
public class Singleton {
private static final Singleton instance = new Singleton();
private Singleton() {}
public static Singleton getInstance() {
return instance;
}
}
“如果程序使用该类,但可能不是单例实例本身,那么您可能希望切换到延迟初始化。”
1 - 不确定我是否得到了它。为什么程序不能使用类?为什么我不能通过添加属性/方法来解决它?恒定参考应如何改变?
2 - 在延迟初始化中 - 假设多线程发生,同步getInstance()而不是代码块(摆脱双重检查)会如何影响我的程序?
谢谢。
答案 0 :(得分:4)
1 - 您的应用程序可能包含各种罐子,但您不一定会使用每个罐子中的所有功能。此外,应用程序的用户可能无法使用您内置的所有功能。例如,如果您有一个ReportABug类,它们可能永远不会从菜单中激活该功能,因为您是一个非常棒的程序员; - )
在运行时需要类之前,不会实例化/调用静态字段/方法,因此ReportABug类可能有1000个静态字段,但是手指交叉,它们永远不会消耗任何内存,因为从不加载类。
他们的观点是,具有单例(或多个)的类可能具有不访问单例的其他静态方法。
2 - 您可以将方法与Singleton类对象同步,但是每次调用getInstance都会产生开销,只需检查instance == null(它是一个机器周期)就便宜得多。有可能另一个线程可以抢占你的线程并在外部== null检查后创建实例,因此两个测试都是必需的。
答案 1 :(得分:2)
synchronized
块,以尽量减少锁争用。答案 2 :(得分:0)
1- java中有很多类,并不总是全部使用它们。如果我用急切初始化定义了一个singelton类,并且你不需要这个类,我最终会浪费内存。
答案 3 :(得分:0)
实践中的参考并发16.7双重检查锁定反模式。不要这样做。