java - 单例 - 实例化类的最佳方式

标签 java singleton

我正在查看 Telegrams 的 Messenger 源代码,我注意到它们的单例类都在其 getInstance 方法上使用局部变量,如下所示。例如,在他们的 Android GitHub repo 上, 上课 NotificationsController.java他们有以下内容:

private static volatile NotificationsController Instance = null;
public static NotificationsController getInstance() {
    NotificationsController localInstance = Instance;
    if (localInstance == null) {
        synchronized (MessagesController.class) {
            localInstance = Instance;
            if (localInstance == null) {
                Instance = localInstance = new NotificationsController();
            }
        }
    }
    return localInstance;
}

我不完全确定本地变量“localInstance”的用途是什么。谁能准确解释“localInstance”变量的用途是什么?没有它就不能实现同样的目标吗,就像下面的代码一样?

private static volatile NotificationsController Instance = null;
public static NotificationsController getInstance() {
    if (Instance == null) {
        synchronized (MessagesController.class) {
            if (Instance == null) {
                Instance = new NotificationsController();
            }
        }
    }
    return Instance;
}

最佳答案

这样做是出于性能原因。

考虑变量已初始化的最常见场景。编写的代码将读取 volatile 变量一次并返回值。你的版本会读两遍。由于 volatile 读取会带来轻微的性能成本,因此使用局部变量会更快。

因为在您的情况下,延迟初始化的变量是静态的,所以最好使用 holder class 惯用语。参见 this answer举个例子。

关于java - 单例 - 实例化类的最佳方式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35857270/

相关文章:

java - Android 在旋转设备或在未注销的情况下重新打开 APP 时丢失内容

Java:类.this

java - R Shiny DesktopDeployR 停止日志记录错误

actionscript-3 - 管理外部 swf 中的单例

c++ - 在初始化列表中创建单例对象会导致访问冲突(仅限 Release模式)

java - 从接口(interface)访问单例的引用,可以吗?

java - 零除 Java 整数与 double

用于创建 Windows 安装程序的 Java 库

ios - 如何拥有相同更新的对象的多个副本,同时在不同 View Controller 中实例化为单独的对象?

java - 可观察类可以构造为单例吗?