Home Articles

使用Kotlin在Android中安装线程安全的全局资源

Asked
Viewed 255 times
0

我是Android应用程序的新手,活动生命周期似乎迫使对全局变量的依赖 . (即使使用Dagger,也会有有状态的全局Dagger对象执行依赖注入 . )

我想创建一个名为 GlobalMode 的全局可用模式对象 . 该模式应该在运行时可以更改 . 这是我到目前为止:

interface Mode {
    fun doSomething(a: Int);
}

class NormalMode : Mode {
    override fun doSomething(a: Int) {
        // ...
    }
}

class DebugMode : Mode {
    override fun doSomething(a: Int) {
        // ...
    }
}

object GlobalMode : Mode {

    private var mode: Mode? = null;

    private fun getMode() : Mode {
        if (this.mode == null) {
            this.mode = NormalMode();
        }
        return this.mode!!;
    }

    fun setMode(mode: Mode) {
        this.mode = mode;
    }

    override fun doSomething(a: Int) {
        this.getMode().doSomething(a = a);
    }

}

Kotlin object 声明非常适合制作全局对象 . 它肯定比Java中的单例模式更好 . 我喜欢如何声明全局对象来实现 Mode 接口 .

我不知道怎么做是让以下部分线程安全 . 如果 NormalMode 的实例化很昂贵,则两个线程可能导致昂贵的实例化,因为 null 检查中没有同步化 .

if (this.mode == null) {
            this.mode = NormalMode();
        }

我想做这样的事情,因为显然 lazy 初始化是线程安全的 .

object GlobalMode : Mode {

    private var mode: Mode? = null;

    private val defaultMode: Mode by lazy {
        NormalMode();
    }

    private fun getMode() : Mode {
        if (this.mode == null) {
            this.mode = this.defaultMode;
        }
        return this.mode!!;
    }

    // ...

}

这个 lazy 方法的问题是,一旦分配了 defaultMode ,它就是永久性的 . 如果在运行时发生某些事情以更改其余应用程序生命周期的模式, defaultMode 仍然保留对 NormalMode 对象的强引用,这意味着永远不会对对象进行垃圾回收 . 它永远不会再次使用,但它永远不会被垃圾收集 .

如何以更好的方式使以下部分线程安全?

if (this.mode == null) {
            this.mode = NormalMode();
        }

谢谢 .

1 Answer

  • 2

    与Java类似,您可以使方法同步:

    @Synchronized private fun getMode() : Mode {
        if (this.mode == null) {
            this.mode = this.defaultMode;
        }
        return this.mode!!;
    }
    

Related