【问题标题】:how to write getter and setter containing mutex.withLock in kotlin如何在 kotlin 中编写包含 mutex.withLock 的 getter 和 setter
【发布时间】:2020-06-16 10:34:17
【问题描述】:

我想从协程中同步访问代表我的状态的变量。我该如何解决这个问题?

private var myState: MyState? = null
    get() = mutex.withLock {
        return@withLock myState
    }
    set(value) = mutex.withLock {
        field = value
    }
private val mutex = Mutex()    

现在我收到Suspend function 'withLock' should be called only from a coroutine or another suspend function 消息。 如果不可能有任何替代的优雅解决方案?

【问题讨论】:

标签: kotlin getter-setter kotlin-coroutines


【解决方案1】:

在非挂起上下文中调用挂起函数。你可以使用runBlocking

private var myState: MyState? = null
    get() {
        return runBlocking {
            mutex.withLock {
                myState
            }
        }
    }
    set(value) {
        runBlocking {
            mutex.withLock {
                field = value
            }
        }
    }
private val mutex = Mutex()    

注意事项:

最好将属性更改为两个挂起函数(getter/setter),而不是使用runBlocking。 一切都取决于您调用myState 的上下文。

您还想考虑为KT-15555 投票。

【讨论】:

  • 来自runBlocking 的文档:Runs a new coroutine and blocks the current thread interruptibly until its completion. This function should not be used from a coroutine. It is designed to bridge regular blocking code to libraries that are written in suspending style, to be used in main functions and in tests. 所以使用runBlocking 我无法从协程获取/设置变量。正如您当时建议的那样,两个挂起函数(getter/setter)要好得多
  • 不是你不能,而是你不应该。 (除非您的调度程序是单线程的,否则它会死锁)。如果您从其他协程调用,那么您肯定需要两个挂起函数。我还使用您可能希望看到的链接更新了我的答案。
猜你喜欢
  • 2019-01-07
  • 2016-10-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多