提问人:Yu Xing 提问时间:9/15/2023 最后编辑:Basil BourqueYu Xing 更新时间:9/15/2023 访问量:57
单例模式中 Eager Initialization 和 Lazy Initialization 的区别
the Difference between Eager Initialization and Lazy Initialization in Singleton Pattern
问:
我找到了两种不同的方法来实现单例模式,它们是延迟初始化和快速初始化。代码为:
public class EagerSingleton {
private static final EagerSingleton instance = new EagerSingleton();
private EagerSingleton() {
}
public static EagerSingleton getInstance() {
return instance;
}
}
...和:
public class LazySingleton {
private static LazySingleton instance;
private LazySingleton() {
}
public static synchronized LazySingleton getInstance() {
if (instance == null) {
instance = new LazySingleton();
}
return instance;
}
}
据说这两种方式的区别在于,在类加载过程中初始化较早,在首次使用时初始化较晚。但是我看不到时间差异,因为它们都有私有构造函数,这意味着您不能在不使用的情况下创建实例并让它(这可以看到时间差异)。唯一的方法是使用该方法。因此,当您使用此方法时,类加载过程和两者都在此时发生。所以它们似乎没有什么不同。EagerSingleton
LazySingleton
new
getInstance()
getInstance()
有人可以解释一下这个例子中的区别吗?
答:
1赞
Reilas
9/15/2023
#1
"...据说这两种方式的区别在于,EagerSingleton 在类加载过程中初始化较早,而 LazySingleton 在首次使用时初始化较晚。..."
正确,EagerSingleton 类将在类初始化期间实例化实例字段。
而 LazySingleton 类将等待调用 getInstance 方法。
"...我看不到时序差异,因为它们都有私有构造函数,这意味着你不能通过new创建一个实例,让它不使用(这可以看到时序差异)。..."
您可以利用类初始化块来评估字段。
请考虑以下几点。
public class EagerSingleton {
private static final EagerSingleton instance = new EagerSingleton();
static {
System.out.println("EagerSingleton instantiated");
}
private EagerSingleton() {
}
public static EagerSingleton getInstance() {
System.out.println("EagerSingleton returned instance");
return instance;
}
}
public class LazySingleton {
private static LazySingleton instance;
static {
System.out.println("LazySingleton not instantiated");
}
private LazySingleton() {
}
public static synchronized LazySingleton getInstance() {
System.out.println("LazySingleton checking instance");
if (instance == null) {
System.out.println("LazySingleton instance assigned");
instance = new LazySingleton();
}
System.out.println("LazySingleton returned instance");
return instance;
}
}
现在,创建 2 个 EagerSingleton 和 2 个 LazySingleton 对象。
System.out.println("e1");
EagerSingleton e1 = EagerSingleton.getInstance();
System.out.printf("%nl1%n");
LazySingleton l1 = LazySingleton.getInstance();
System.out.printf("%ne2%n");
EagerSingleton e2 = EagerSingleton.getInstance();
System.out.printf("%nl2%n");
LazySingleton l2 = LazySingleton.getInstance();
输出
e1
EagerSingleton instantiated
EagerSingleton returned instance
l1
LazySingleton not instantiated
LazySingleton checking instance
LazySingleton instance assigned
LazySingleton returned instance
e2
EagerSingleton returned instance
l2
LazySingleton checking instance
LazySingleton returned instance
评论
0赞
Yu Xing
9/15/2023
谢谢你的例子。但是,一些消息来源声称 EagerSingleton 可能会导致不必要的内存开销。但是当我看到这个例子时,我没有看到它在实际应用中发生,因为它们之间只有很小的时间差。
评论