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

我是新来的Android应用程序和活动lifecyle似乎强制对全局的依赖。 (即使有Dagger,也有执行dependency injection的有状态的全局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(); } 

谢谢。

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

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