我正在使用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()
}
}
根据withLock
实现,互斥锁是在堆栈帧,这意味着,在withLock
执行互斥锁被释放,但代码异步可能不执行正确的帧(根据当前调度程序)也许在另一个线程,所以可能当异步执行的块,withLock
调用可能已经回来,至于also
调用,它被标记为inline
,这在当前帧中执行,之前withLock
返回
互斥锁在任何时候最多由一个协程持有。async
启动一个不试图获取互斥锁的协程。这和其他互斥锁的意义是一样的——async
块内的代码不受互斥锁保护,所以它不能触及需要被它保护的状态。