如果按如下方式实现单例,
class Singleton {
private static Singleton instance = new Singleton();
public static Singleton getInstance() {
return instance;
}
}这种实现与惰性初始化方法有什么不同?在这种情况下,实例将在装入类时创建,并且类本身仅在第一次活动使用时装入(例如,Singleton.getInstance(),而不是在为实例声明Singleton singleton =null时;)
即使使用延迟初始化方法,实例也是在调用getInstance()时创建的
我是不是漏掉了什么?
发布于 2011-10-17 15:00:26
您也可以调用任何其他静态方法或静态成员变量来加载单例实例。
class Logger {
private static Logger instance = new Logger();
public static String LOG_LINE_SEPERATOR =
System.getProperty("line.separator");
public static Logger getInstance() {
return instance;
}
public static String logPattern() {
return null;
}
} ..。
Logger.LOG_LINE_SEPERATOR; // load Logger instance or
Logger.logPattern(); // load Logger instance发布于 2011-10-17 14:51:51
使用延迟初始化,您仅在需要实例时创建实例,而不是在装入类时创建实例。因此,您可以避免不必要的对象创建。话虽如此,但还有其他事情需要考虑。在延迟初始化中,您需要提供一个公共API来获取实例。在多线程环境中,避免不必要的对象创建带来了挑战。你放置同步块来检查已经创建的对象,这会造成不必要的锁定。因此,在这种情况下,这会成为一个性能问题。
因此,如果您确定创建对象不会占用大量内存,并且几乎总是在应用程序中使用,那么在静态初始化中创建对象是很好的。此外,请不要忘记在这种情况下使您的实例是最终的,因为它确保对象创建正确地反映到主存中,这在多线程环境中很重要。
请参阅IBM在Singleton+惰性Loading+多线程环境上的此tutorial案例
2018年9月9日的===============Edit =
您还应该查看对象创建on demand pattern here。
发布于 2011-10-17 15:47:29
由于您提到的原因,这只是一种更复杂的方法,它的作用与
enum Singleton {
INSTANCE;
}只有当您担心类可能被初始化,但又不想在此时加载单例时,使用惰性初始化才有用。在大多数情况下,这都是过杀。
注意:仅仅引用类并不会初始化类。
例如,假设你有一个写得很糟糕的类,除非设置了一些条件,否则它不能初始化。在这种情况下,n必须为非零。
public class Main {
public static void main(String ... args) {
Class c= LazyLoaded.class;
System.out.println(c);
}
static class LazyLoaded {
static int n = 0;
static {
System.out.println("Inverse "+1000/n);
}
}
}打印
class Main$LazyLoadedhttps://stackoverflow.com/questions/7790185
复制相似问题