我发现两种不同的方法来实现单例模式,它们是延迟初始化和急切初始化。代码是:
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()
都发生在这个时候。所以看起来他们并没有什么不同。
有人可以解释一下这个例子中的区别吗?
“...据说这两种方式的区别是EagerSingleton在类加载过程中初始化较早,而LazySingleton在第一次使用时初始化较晚。...”
正确,EagerSingleton类将在类初始化期间实例化instance字段。
而 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 对象。
EagerSingleton e1 = EagerSingleton.getInstance();
LazySingleton l1 = LazySingleton.getInstance();
EagerSingleton e2 = EagerSingleton.getInstance();
LazySingleton l2 = LazySingleton.getInstance();
输出
EagerSingleton instantiated
EagerSingleton returned instance
LazySingleton not instantiated
LazySingleton checking instance
LazySingleton instance assigned
LazySingleton returned instance
EagerSingleton returned instance
LazySingleton checking instance
LazySingleton returned instance
”...唯一的办法就是使用getInstance()方法。所以当你使用这个方法时,类加载过程和getInstance()都发生在这个时候。所以看起来他们没有什么不同。有人可以吗解释一下这个例子中的区别?”
这里唯一真正的区别是,在 LazySingleton getInstance 中有一个额外的 条件语句,用于检查 null。