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 返回

之前