用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!!; }