不正确的惰性初始化

2022-08-31 16:06:26

Findbug告诉我,我使用了不正确的惰性初始化。

public static Object getInstance() {
    if (instance != null) {
        return instance;
    }

    instance = new Object();
    return instance;
}

我在这里没有看到任何错误。是发现虫的错误行为,还是我错过了什么?


答案 1

Findbug 引用了一个潜在的线程问题。在多线程环境中,可能会使用当前代码多次创建单例。

这里有很多阅读,但它将有助于解释。

此处的争用条件位于 .在第一次调用时,线程将进入 ,并将创建实例并将其分配给“实例”。但是,在 实例创建/分配 和 之间,另一个线程可能会变为活动状态。此线程也可以传递,因为分配尚未发生。因此,将创建两个(或更多,如果有更多的线程进入)实例,并且线程将具有对不同对象的引用。if checkif checkif checkif check


答案 2

您的代码比所需的代码稍微复杂一些,这可能就是它混淆的原因。

编辑:这绝对是其他人发布的线程问题,但我想我会在这里发布双锁检查实现以供参考:

private static final Object lock = new Object();
private static volatile Object instance; // must be declared volatile

public static Object getInstance() {
    if (instance == null) { // avoid sync penalty if we can
        synchronized (lock) { // declare a private static Object to use for mutex
            if (instance == null) {  // have to do this inside the sync
                instance = new Object();
            }
        }
    }

    return instance;
}

推荐