Android get实例导致的kotlin.UninitializedPropertyAccessException异常

Android get实例导致的kotlin.UninitializedPropertyAccessException异常,android,kotlin,initialization,locking,Android,Kotlin,Initialization,Locking,我的manager类有以下代码: 11 class MyManager private constructor(application: Application) { 12 companion object { 13 val TAG = MyManager::class.java.simpleName 14 15 private val initialized = AtomicBoolean(false) 16 private lateinit v

我的manager类有以下代码:

11 class MyManager private constructor(application: Application) {
12    companion object {
13        val TAG = MyManager::class.java.simpleName
14
15        private val initialized = AtomicBoolean(false)
16        private lateinit var instance: MyManager
17
18        fun initialize(application: Application) {
19            synchronized(initialized) {
20                if (!initialized.getAndSet(true)) {
21                    instance = MyManager(application)
22                }
23            }
24        }
25
26        val INSTANCE get() = instance
27    }
对于我的一些应用程序用户来说,它正在崩溃

 val INSTANCE get() = instance
线

使用以下崩溃堆栈

kotlin.UninitializedPropertyAccessException: 
  at my.package.MyManager$Companion.getINSTANCE (MyManager.kt:26)
  at my.package.MyOtherManager.systemInitialization (MyOtherManager.kt:585)
  at my.package.MyOtherManager.doRun (MyOtherManager.kt:433)
  at my.package.MyOtherManager.access$doRun (MyOtherManager.kt:56)
  at my.package.MyOtherManager$launchThread$launched$1$1.invoke (MyOtherManager.kt:126)
  at my.package.MyOtherManager$launchThread$launched$1$1.invoke (MyOtherManager.kt:56)
  at my.package.MyOtherManagerKt$sam$i$java_lang_Runnable$0.run (Unknown Source:2)
  at java.lang.Thread.run (Thread.java:919)
  
  
我从类似错误中了解到的是,我在设置实例之前先获取实例,但如果默认情况下我的
initialized
布尔值为false,并且我正在设置
instance
变量,我看不出这是怎么可能的

我实例化类的方式有问题吗?
当我调用
synchronized
时,我的第19行的行为是什么?它是先等待执行它,然后再转到第26行(获取实例),还是在调用
synchronized
块中的代码之前获取实例存在风险?

此代码有一些问题

当我调用
synchronized
时,我的第19行的行为是什么?它是否先等待执行它,然后再转到第26行(获取实例)

这些代码行没有强制关系。在读取
实例
属性之前调用
initialize(…)
是没有强制要求的。您需要确保在每次访问
实例
(或
实例
)之前调用
初始化

另一个问题是,在这里使用同步有点奇怪。您有一个
synchronized
块,好像您希望从多个线程调用
initiaize
,但它只是用
应用程序初始化的。这不是必需的,只需在应用程序启动时调用一次即可


另一个问题是,根据具体的设置方式,可能存在线程安全问题。如果您正在从另一个线程读取此信息,并且
实例
的初始化不作为该另一个线程的开始,则该初始化可能对该另一个线程不可见。您可以通过使
实例
易失性

来解决此问题。您确定在每次读取
实例
之前都要调用
初始化
吗?您是对的,初始化之前我可能有一个实例调用请回答。关于
volatile
用法,如果我这样做,我需要将它添加到
initialized
和ìnstance`变量中?