Тематический глобальный ресурс в Android с Kotlin

Я новичок в приложениях для Android, и действие lifecyle, похоже, заставляет полагаться на глобальные переменные. (Даже с кинжалом есть объекты с целостным состоянием, глобальные объекты кинжала, которые выполняют инъекцию зависимостей.)

Я хотел бы создать глобально доступный объект режима 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); } } 

Объявление object Kotlin отлично подходит для создания глобального объекта. Это определенно кажется лучше, чем одноэлементный шаблон в 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!!; }