asc*_*sco 2 synchronized kotlin kotlin-coroutines
我有以下课程:
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() {}
}
Run Code Online (Sandbox Code Playgroud)
在我能做之前useSdk(),我必须调用sdk.init(),但sdk.init()只能调用一次,不能多次。
使用我当前的解决方案,如果doSomething快速调用两次(第二次发生在sdk.init()仍在运行时),我会调用sdk.init()两次,因为inited: Boolean仍然是false。
如果我像这样移动 up 的分配inited:
private fun init() {
inited = true
sdk.init()
}
Run Code Online (Sandbox Code Playgroud)
并且被快速调用两次,第二次调用将在其完成doSomething()之前使用 SDK 。init()
我尝试用以下方法解决这个问题:
suspend fun doSomething() = synchronized(this){
withContext(Dispatchers.IO) {
if (inited.not()) init()
useSdk()
}
}
Run Code Online (Sandbox Code Playgroud)
但在 IntelliJ 中收到错误:
withContext 挂起点位于关键部分内
我认为这synchronized在这里不起作用,因为我们离开主线程并在块仍在运行doSomething()时完成?withContext
我如何解决手头的问题,基本上是:doSomething()一次只能运行一次?
Gle*_*val 15
synchronized {...}您可以使用互斥锁来代替:
class SdkWrapper(private val sdk: Sdk) {
...
private val mutex = Mutex()
suspend fun doSomething() = mutex.withLock {
withContext(Dispatchers.IO) {
if (inited.not()) init()
useSdk()
}
}
...
}
Run Code Online (Sandbox Code Playgroud)
你可以在这里查看关于协程和互斥的官方文档。
| 归档时间: |
|
| 查看次数: |
2908 次 |
| 最近记录: |