Mutex 不保存在此异步块中
Mutex is not held in this async block
我正在使用 Kotlin 流程和 LiveData 代码实验室执行高级协程,并在 CacheOnSuccess.kt
中遇到了这个函数。
有一条评论说“// 注意:此异步块中不包含互斥量”。这到底是什么意思?为什么不将互斥锁保存在异步块中?那有什么意义呢?
suspend fun getOrAwait(): T {
return supervisorScope {
// This function is thread-safe _iff_ deferred is @Volatile and all reads and writes
// hold the mutex.
// only allow one coroutine to try running block at a time by using a coroutine-base
// Mutex
val currentDeferred = mutex.withLock {
deferred?.let { return@withLock it }
async {
// Note: mutex is not held in this async block
block()
}.also {
// Note: mutex is held here
deferred = it
}
}
// await the result, with our custom error handling
currentDeferred.safeAwait()
}
}
互斥量在任何时候最多由一个协程持有。 async
启动一个不尝试获取互斥锁的协程。其重要性与任何其他互斥锁相同——async
块内的代码不受互斥锁保护,因此它不能触及需要由它保护的状态。
根据 withLock
实现,互斥量被保存在刚刚的堆栈帧中,这意味着,在 withLock
执行后互斥量被释放,但是异步 中的代码可能 不在该帧中正确执行(根据当前的 Dispatchers,可能在另一个线程中执行),因此可能在执行异步块时,withLock
调用可能已经返回,至于 also
调用,它被标记为 inline
,因此它在当前帧中执行,就在 withLock
返回
之前
我正在使用 Kotlin 流程和 LiveData 代码实验室执行高级协程,并在 CacheOnSuccess.kt
中遇到了这个函数。
有一条评论说“// 注意:此异步块中不包含互斥量”。这到底是什么意思?为什么不将互斥锁保存在异步块中?那有什么意义呢?
suspend fun getOrAwait(): T {
return supervisorScope {
// This function is thread-safe _iff_ deferred is @Volatile and all reads and writes
// hold the mutex.
// only allow one coroutine to try running block at a time by using a coroutine-base
// Mutex
val currentDeferred = mutex.withLock {
deferred?.let { return@withLock it }
async {
// Note: mutex is not held in this async block
block()
}.also {
// Note: mutex is held here
deferred = it
}
}
// await the result, with our custom error handling
currentDeferred.safeAwait()
}
}
互斥量在任何时候最多由一个协程持有。 async
启动一个不尝试获取互斥锁的协程。其重要性与任何其他互斥锁相同——async
块内的代码不受互斥锁保护,因此它不能触及需要由它保护的状态。
根据 withLock
实现,互斥量被保存在刚刚的堆栈帧中,这意味着,在 withLock
执行后互斥量被释放,但是异步 中的代码可能 不在该帧中正确执行(根据当前的 Dispatchers,可能在另一个线程中执行),因此可能在执行异步块时,withLock
调用可能已经返回,至于 also
调用,它被标记为 inline
,因此它在当前帧中执行,就在 withLock
返回