首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >同步与withContext

同步与withContext
EN

Stack Overflow用户
提问于 2020-10-09 09:09:11
回答 1查看 1.3K关注 0票数 0

我有以下课程:

代码语言:javascript
复制
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的分配向上移动,如下所示:

代码语言:javascript
复制
private fun init() {
    inited = true
    sdk.init()
}

doSomething()被快速调用了两次,第二个调用将在其‘init()’完成之前使用sdk。

我试着用:

代码语言:javascript
复制
suspend fun doSomething() = synchronized(this){
    withContext(Dispatchers.IO) {
        if (inited.not()) init()
        useSdk()
    }
}

但是在IntelliJ中接收一个错误:

withContext暂停点在一个关键区域内。

我假设synchronized无论如何不会在这里工作,因为我们离开了主线程,而doSomething()是在withContext块还在运行时完成的?

我如何解决手头的问题,基本上是:doSomething()一次只能运行一次?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2020-10-09 10:34:53

您可以使用Mutex代替synchronized {...}

代码语言:javascript
复制
class SdkWrapper(private val sdk: Sdk) {

    ...

    private val mutex = Mutex()

    suspend fun doSomething() = mutex.withLock {
        withContext(Dispatchers.IO) {
            if (inited.not()) init()
            useSdk()
        }
    }

    ...

}

您可以查看有关Coroutines和互斥这里的官方文档。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/64277015

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档