单例模式中急切初始化和惰性初始化的区别

问题描述 投票:0回答:1

我发现两种不同的方法来实现单例模式,它们是延迟初始化和急切初始化。代码是:

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()
都发生在这个时候。所以看起来他们并没有什么不同。

有人可以解释一下这个例子中的区别吗?

java singleton eager-loading lazy-initialization
1个回答
0
投票

“...据说这两种方式的区别是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

© www.soinside.com 2019 - 2024. All rights reserved.