Android get实例导致的kotlin.UninitializedPropertyAccessException异常
我的manager类有以下代码: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
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`变量中?