如何在Coroutines中实现原子更新
这是Coroutines stateflow的更新功能。我有两个问题:
- 原子如何?我们内部有多次操作,如何在不相互排斥的情况下保证原子能?
- 为什么在(true)循环中?在什么条件下,循环是必要的?
- 循环可以无尽吗?
/**
* 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
}
}
}
Here's update function from Coroutines StateFlow. I have two questions:
- How is it atomic? We have multiple operations inside, how can atomicity be guaranteed without mutual exclusion?
- Why is it in while(true) loop? At what condition the loop is necessary?
- Can the loop be endless?
/**
* 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
}
}
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
更新
操作本身不是原子,其中有多个操作。但是,它实际交换了新状态的过时状态的部分:compareAndset(prevvalue,nextValue)
是原子。prevvalue
,然后新值应通过在prevvalue
上运行lambda,函数
。这为我们提供了nextValue
。现在,我们需要记住,我们必须运行线程安全代码,因此prevvalue
在运行该函数时可能会更改,因此,compareandset(prevvalue,nextValue)< /code>执行以下内容(从Kotlin引用):“从原子上将当前值与期望进行比较,并将其设置为如果等于期望。因此,这意味着如果
prevvalue
与当前值不满(这意味着另一个线程在运行函数时已更新了当前值),那么我们应该再次重复整个循环,否则我们返回。此方法保证了线程安全性,我们将永远不会覆盖另一个线程的更改,反之亦然!中的所有循环一样,(true)
在有条件的休息中,此循环将无限期地运行,直到concormeandset
返回true
。撇开这几天,我前几天学到了一些东西:kotlin coroutines继承iSACTIVE
,您可以使用它来创建一个合规的coroutine,当执行while(isacative)
时,可以取消示波器时取消/代码>。很少是
,而(true)
是一个好主意:)update
operation itself isn't atomic, there are multiple operations within it. However, the part where it actually swaps out the out-of-date state for the new state:compareAndSet(prevValue, nextValue)
is atomic.prevValue
and then what the new value should be by running the lambda,function
onprevValue
. This gives us thenextValue
. Now, we need to remember that we must be running thread-safe code, so theprevValue
might have changed while we were running the function, for this reason,compareAndSet(prevValue, nextValue)
does the following (from the Kotlin reference): "Atomically compares the current value with expect and sets it to update if it is equal to expect. The result is true if the value was set to update and false otherwise.". So, what this means is that ifprevValue
is out of date with the current value (this means that another thread has updated the current value while we were running the function) then we should repeat the whole loop again, otherwise we return. This method guarantees thread safety, we will never overwrite changes from another thread and vice versa!while(true)
with a conditioned break, this loop will run indefinitely, untilcompareAndSet
returnstrue
. Just as an aside to this, something I learned the other day: Kotlin coroutines inheritisActive
, you can use this to create a compliant coroutine that can cancel when the scope is shut down by doingwhile(isActive)
. Rarely iswhile(true)
a good idea :)