Gregory Kick了解dagger2 ScopedProvider中的惰性初始化单例

zhang xuefeng

我正在阅读Dagger2的源代码,并且其中ScopedProvider有一个静态字段UNINITIALIZED,用于指示该instance字段尚未初始化。我已经阅读并理解了double-check-lazy-initialization惯用语,但是为什么有必要定义该UNINITIALIZED字段而不是仅仅使用null与JVM有关吗?

/**
 * A {@link Provider} implementation that memoizes the result of a {@link Factory} instance.
 *
 * @author Gregory Kick
 * @since 2.0
 */
public final class ScopedProvider<T> implements Provider<T> {
    private static final Object UNINITIALIZED = new Object();

    private final Factory<T> factory;
    private volatile Object instance = UNINITIALIZED;

    private ScopedProvider(Factory<T> factory) {
        assert factory != null;
        this.factory = factory;
    }

    @SuppressWarnings("unchecked") // cast only happens when result comes from the factory
    @Override
    public T get() {
        // double-check idiom from EJ2: Item 71
        Object result = instance;
        if (result == UNINITIALIZED) {
            synchronized (this) {
                result = instance;
                if (result == UNINITIALIZED) {
                    instance = result = factory.get();
                }
            }
        }
        return (T) result;
    }

    /** Returns a new scoped provider for the given factory. */
    public static <T> Provider<T> create(Factory<T> factory) {
        if (factory == null) {
            throw new NullPointerException();
        }
        return new ScopedProvider<T>(factory);
    }
}
约翰·H

看起来这是一个懒惰的null安全初始化。想象一下,如果工厂返回的是null,而该代码而不是UNINITIALIZED则使用null作为标记值。每次调用get()都会进入同步块,因为它不知道null是否实际上是出厂结果,而不仅仅是未初始化的状态。

此代码允许工厂返回null并将结果正确存储在volatile字段中,以便后续读取不会产生完全同步的开销。

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

如何在 Hilt dagger 中重新初始化单例组件?

Dagger2 + Kotlin:lateinit属性尚未初始化

Dagger2单例注释不起作用

Android Dagger2,单例交叉组件

启动单例 bean 能否延迟 J2EE 容器初始化?

使用dagger2更改在应用程序类中初始化的改造基本URL

MVP + Dagger2 + Kotlin:lateinit属性演示者尚未初始化

带有Dagger2的Android Kotlin,lateinit var尚未初始化

使用 dagger2 初始化 WorkManger 时使用“WorkContinuation.combine()”时出现的问题

Dagger2单例实际上不是单例问题

Dagger2:从单例组件返回非单例对象

如果使用 Dagger2 初始化对象,是否仍然需要检查对象是否为空?

在 Android 6.0 中使用 Dagger2 初始化 Worker 时,应用程序不断崩溃

spring组件扫描是将所有对象初始化为单例还是惰性初始化?

dagger2中如何建立循环依赖模型?

如何在Dagger2中提供视图?

dagger2中的不同@Singleton和静态@Provides

如何使用Dagger2将ViewModel注入BottomSheetDialogFragment中?

Kotlin Dagger2中的适配器依赖注入

相关组件中的Dagger2和限定符

Android 中的 Dagger2 范围和 RepositoryPattern

Dagger2 vs Android中的Application类

Dagger2中的静态提供方法

Dagger2中模块和组件之间的区别

Dagger2在Module中创建接口的重复实例

Dagger 2单例在多个实例中

不能使dagger2将改造API注入单例对象,然后将该单例对象注入片段

Java中的单例模式。延迟初始化

静态单例内联初始化中的NullReferenceException