#mutex #android-livedata #flow #kotlin-coroutines
Вопрос:
Я выполняю расширенные сопрограммы с помощью Kotlin flow и лаборатории кода 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()
}
}
Ответ №1:
по данным withLock
осуществления, мьютекс удерживается на просто стек-кадр, а значит, после withLock
выполнения мьютекс освобождается, но код внутри асинхронного может не выполнить правы в том, что рама (возможно, в другом потоке по текущим диспетчеров), так что, вероятно, когда блок асинхронного казнят, withLock
вызов может уже вернулись, как для also
вызова, он помечается как inline
, таким образом, он выполняется в текущем кадре, прямо перед withLock
возвращается
Ответ №2:
Мьютекс удерживается не более чем одной сопрограммой в любое время. async
запускает сопрограмму, которая не пытается получить мьютекс. Значение этого такое же, как и для любого другого мьютекса-код внутри async
блока не защищен мьютексом, поэтому он не должен касаться состояния, которое требуется для его защиты.