java多线程惰性初始化单例哪种方法?
以下两种在java中惰性初始化线程安全单例的方法都正确吗?性能有什么不同吗?如果没有,为什么我们要使用Holder模式(Singleton2),而不是像Singleton1那样保持简单 提前谢谢java多线程惰性初始化单例哪种方法?,java,multithreading,thread-safety,singleton,lazy-initialization,Java,Multithreading,Thread Safety,Singleton,Lazy Initialization,以下两种在java中惰性初始化线程安全单例的方法都正确吗?性能有什么不同吗?如果没有,为什么我们要使用Holder模式(Singleton2),而不是像Singleton1那样保持简单 提前谢谢 class Singleton1 { private Singleton1() { System.out.println("Singleton1-Constructor"); } private static final Singleton1 inst1 = n
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.
}
}
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构造函数,因为它确实是懒惰的。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构造函数,因为它确实是懒惰的。第二个选项的可能副本,
Singleton2
,允许您在不触发实例构造的情况下执行其他静态方法(如果有的话)。但是,通常情况下,Holder
类是private static
,您可以在singleton类上使用public static
方法公开实例。至少我一直都是这么看的。对于那些认为它是重复的人…请看下面Pietro Boido提供的解释。建议职位上没有人以同样的方式解释过。有些人需要更多的解释,所以请不要忽略问题,因为你认为已经有类似的问题了。谢谢,请看一下彼得罗·博伊多在回答中所说的。但是,我认为Pietro更直接。第二个选项的可能副本,Singleton2
,允许您在不触发实例构造的情况下执行其他静态方法(如果有的话)。但是,通常情况下,Holder
类是private static
,您可以在singleton类上使用public static
方法公开实例。至少我一直都是这么看的。对于那些认为它是重复的人…请看下面Pietro Boido提供的解释。建议职位上没有人以同样的方式解释过。有些人需要更多的解释,所以请不要忽略问题,因为你认为已经有类似的问题了。谢谢,请看一下彼得罗·博伊多在回答中所说的。不过,我会说,我认为皮埃特罗更直接。谢谢皮埃特罗·博伊多的详细答复。但是从线程安全的角度来看,这两种解决方案都是安全的吗?谢谢Pietro Boido的详细回复。但是从线程安全的角度来看,这两种解决方案都是安全的吗?