首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >最近查看了大量第三方库代码,并看到了这段代码,这让我很困惑。

最近查看了大量第三方库代码,并看到了这段代码,这让我很困惑。
EN

Stack Overflow用户
提问于 2018-12-25 11:22:17
回答 1查看 58关注 0票数 1

下面是来自EventBus getDefault()静态方法的代码,它返回EventBus类的静态实例。

代码语言:javascript
复制
/** Convenience singleton for apps using a process-wide EventBus instance. */
public static EventBus getDefault() {
    EventBus instance = defaultInstance;
    if (instance == null) {
        synchronized (EventBus.class) {
            instance = EventBus.defaultInstance;
            if (instance == null) {
                instance = EventBus.defaultInstance = new EventBus();
            }
        }
    }
    return instance;
}

我看到代码首先检查实例是否为null,然后在同步块中再次进行相同的检查。为什么会这样呢。

如果我这样写呢。

代码语言:javascript
复制
/** Convenience singleton for apps using a process-wide EventBus instance. */
public static EventBus getDefault() {
    EventBus instance = defaultInstance;
    if (instance == null) {
        synchronized (EventBus.class) {
            instance = EventBus.defaultInstance = new EventBus();
        }
    }
    return instance;
}

我的版本有什么问题吗?我在这里错过了什么?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2018-12-25 11:37:30

在代码中,当实例为null时,两个线程可以并发地进入if语句。然后,一个线程进入同步块初始化实例,而另一个线程被阻塞。当第一个线程退出同步块时,等待线程进入并创建另一个Singleton对象。注意,当第二个线程进入同步块时,它不会检查实例是否为非空。

因此,我们遵循双重检查初始化,它包括:

  1. 检查变量是否已初始化(没有获得锁)。如果已初始化,请立即返回它。
  2. 拿到锁。
  3. 反复检查变量是否已经初始化:如果另一个线程首先获得了锁,它可能已经完成了初始化。如果是,则返回初始化变量。
  4. 否则,初始化并返回变量。

来源

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/53921895

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档