这是协程 StateFlow 的更新函数。我有两个问题:
/**
* Updates the [MutableStateFlow.value] atomically using the specified [function] of its value.
*
* [function] may be evaluated multiple times, if [value] is being concurrently updated.
*/
public inline fun <T> MutableStateFlow<T>.update(function: (T) -> T) {
while (true) {
val prevValue = value
val nextValue = function(prevValue)
if (compareAndSet(prevValue, nextValue)) {
return
}
}
}
update
操作本身不是原子的,其中有多个操作。然而,它实际上将过时状态替换为新状态的部分:compareAndSet(prevValue, nextValue)
是原子的。prevValue
中,然后通过运行 lambda 得到新值, function
于 prevValue
。这给了我们nextValue
。现在,我们需要记住,我们必须运行线程安全的代码,因此当我们运行函数时,prevValue
可能会发生变化,因此,compareAndSet(prevValue, nextValue)
会执行以下操作(来自 Kotlin 参考):“原子地将当前值与expect进行比较,如果等于expect则将其设置为update。如果该值设置为update,则结果为true,否则为false。”。因此,这意味着如果 prevValue
与当前值过期(这意味着在我们运行该函数时另一个线程已更新了当前值),那么我们应该再次重复整个循环,否则我们返回。这种方法保证了线程安全,我们永远不会覆盖另一个线程的更改,反之亦然!while(true)
中的所有循环一样,该循环将无限期地运行,直到 compareAndSet
返回 true
。顺便说一句,我前几天学到的东西:Kotlin 协程继承了 isActive
,您可以使用它来创建一个兼容的协程,可以通过执行 while(isActive)
关闭作用域时取消。 while(true)
很少是个好主意:)