以下两种在Java中延迟初始化线程安全单例的方法是否正确?性能上有区别吗?如果不是,那为什么我们使用Holder模式(Singleton2)而不是像Singleton1那样保持简单?
谢谢。
class Singleton1 {
private Singleton1() {
System.out.println("Singleton1-Constructor");
}
private static final Singleton1 inst1 = new Singleton1();
public static Singleton1 getInst1() {
return inst1;
}
}
class Singleton2 {
private Singleton2() {
System.out.println("Singleton2-Constructor");
}
public static class Holder {
private static final Singleton2 holderInst = new Singleton2();
}
public static Singleton2 getInst2() {
return Holder.holderInst;
}
}
public class App {
public static void main(String[] args) {
Singleton1.getInst1(); // without this statement the Singleton1 constructor doesnt get called.
Singleton2.getInst2(); // without this statement the Singleton2 constructor doesnt get called.
}
}
答案 0 :(得分:2)
Singleton1并不是真正的惰性,因为如果您向Singleton1添加任何其他方法并从主类中调用它,那么静态inst1将被初始化。
尝试一下:
public class Singleton1 {
private Singleton1() {
System.out.println("Singleton1-Constructor");
}
private static final Singleton1 inst1 = new Singleton1();
public static Singleton1 getInst1() {
return inst1;
}
public static void foo() {
}
}
public class Singleton2 {
private Singleton2() {
System.out.println("Singleton2-Constructor");
}
public static class Holder {
private static final Singleton2 holderInst = new Singleton2();
}
public static Singleton2 getInst2() {
return Singleton2.Holder.holderInst;
}
public static void bar() {
}
}
public class LazyInitializationApp {
public static void main(String[] args) {
Singleton1.foo();
Singleton2.bar();
}
}
现在运行该应用程序将打印:
Singleton1-Constructor
但是它不会打印Singleton2-Constructor,因为它确实很懒。