【发布时间】:2020-10-09 09:09:11
【问题描述】:
我有以下课程:
class SdkWrapper(private val sdk: Sdk) {
private var inited = false
suspend fun doSomething() = withContext(Dispatchers.IO) {
if (inited.not()) init()
useSdk()
}
private fun init() {
// takes a long time
sdk.init()
inited = true
}
// has to be done asynchronously
// sdk.init() has to have been called before using this
private fun useSdk() {
}
}
class Sdk {
// must only be done once
fun init() {}
}
在我可以调用useSdk()之前,我必须调用sdk.init(),但是sdk.init()只能调用一次,不能多次。
使用我当前的解决方案,如果doSomething 被快速调用两次(第二次在sdk.init() 仍在运行时发生),我会调用sdk.init() 两次,因为inited: Boolean 仍然是false。
如果我将inited 的分配向上移动:
private fun init() {
inited = true
sdk.init()
}
并且doSomething() 被快速调用两次,第二次调用将在其'init() 完成之前使用sdk。
我试图解决这个问题:
suspend fun doSomething() = synchronized(this){
withContext(Dispatchers.IO) {
if (inited.not()) init()
useSdk()
}
}
但在 IntelliJ 中收到错误:
withContext 悬挂点在临界区内
我假设synchronized 无论如何都不会在这里工作,因为我们离开了主线程并且doSomething() 已经完成,而withContext 块仍在运行?
我该如何解决手头的问题,基本上是:doSomething() 一次只能运行一次?
【问题讨论】:
标签: kotlin synchronized kotlin-coroutines