协程中原子更新是如何实现的

问题描述 投票:0回答:1

这是协程 StateFlow 的更新函数。我有两个问题:

  1. 它如何是原子的?我们里面有多个操作,如何保证原子性而不互斥?
  2. 为什么是在 while(true) 循环中?什么情况下需要循环?
  3. 可以无限循环吗?
/**
 * 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
        }
    }
}
atomic kotlin-coroutines
1个回答
0
投票
  1. update
    操作本身不是原子的,其中有多个操作。然而,它实际上将过时状态替换为新状态的部分:
    compareAndSet(prevValue, nextValue)
    是原子的。
  2. 这是聪明的部分:它使用 CAS(比较和设置)技术 - 与我所说的方法调用不同 - 我们将旧值复制到
    prevValue
    中,然后通过运行 lambda 得到新值,
    function
    prevValue
    。这给了我们
    nextValue
    。现在,我们需要记住,我们必须运行线程安全的代码,因此当我们运行函数时,
    prevValue
    可能会发生变化,因此,
    compareAndSet(prevValue, nextValue)
    会执行以下操作(来自 Kotlin 参考):“原子地将当前值与expect进行比较,如果等于expect则将其设置为update。如果该值设置为update,则结果为true,否则为false。”。因此,这意味着如果
    prevValue
    与当前值过期(这意味着在我们运行该函数时另一个线程已更新了当前值),那么我们应该再次重复整个循环,否则我们返回。这种方法保证了线程安全,我们永远不会覆盖另一个线程的更改,反之亦然!
  3. 是的,与带有条件中断的
    while(true)
    中的所有循环一样,该循环将无限期地运行,直到
    compareAndSet
    返回
    true
    。顺便说一句,我前几天学到的东西:Kotlin 协程继承了
    isActive
    ,您可以使用它来创建一个兼容的协程,可以通过执行
    while(isActive)
    关闭作用域时取消。
    while(true)
    很少是个好主意:)
© www.soinside.com 2019 - 2024. All rights reserved.