首页 > 解决方案 > 如何在多线程环境下修改 Kotlin StateFlow 内容?

问题描述

我有一个 MutableStateFlow,它包含一个不可变的数据结构。

必须通过附加值来更改此结构的内容(必须读取 StateFlow.value,必须基于现有对象创建新对象,然后发出)。

在多线程环境中,有可能在一个线程读取 SharedFlow 的内容之后,但在修改回写之前,该内容将被另一个线程修改。然后第一个线程将覆盖更新。

如何确保在多线程环境中永远不会覆盖修改?

到目前为止,我看到了三种解决方法:

还有其他选择吗?我是否缺少一些可以使用的扩展功能?

标签: multithreadingkotlinkotlin-coroutines

解决方案


如果您使用协程处理它,则可以使用带有互斥锁的挂起函数。它就像一个不可重入锁,但在等待时挂起而不是阻塞withLock

private val _myStateFlow: MutableStateFlow<List<Foo>> = ...
val myStateFlow: StateFlow<List<Foo>> get() = _myStateFlow
private val mutex = Mutex()

suspend fun addValue(foo: Foo) {
    mutex.withLock {
        _myStateFlow.value = _myStateFlow.value + foo
    }
}

如果您需要从线程而不是协程添加值,我会使用另一个答案中的 ReentrantLock 。


推荐阅读