multithreading - 如何在多线程环境下修改 Kotlin StateFlow 内容?
问题描述
我有一个 MutableStateFlow,它包含一个不可变的数据结构。
必须通过附加值来更改此结构的内容(必须读取 StateFlow.value,必须基于现有对象创建新对象,然后发出)。
在多线程环境中,有可能在一个线程读取 SharedFlow 的内容之后,但在修改回写之前,该内容将被另一个线程修改。然后第一个线程将覆盖更新。
如何确保在多线程环境中永远不会覆盖修改?
到目前为止,我看到了三种解决方法:
- 使用带有工作人员的队列进行写入
- 使用锁
- 在循环中使用 MutableStateFlow.compareAndSet(继续尝试直到成功)
还有其他选择吗?我是否缺少一些可以使用的扩展功能?
解决方案
如果您使用协程处理它,则可以使用带有互斥锁的挂起函数。它就像一个不可重入锁,但在等待时挂起而不是阻塞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 。
推荐阅读
- php - Wordpress PHP:将帖子与类别存档上的自定义帖子类型结合起来
- c++ - CNTK:->Forward 或 ->Evaluate crash 在某些 PC 上,而不是在其他 PC 上
- python - Python Klein - 如何将 Excel 文件作为附件返回?
- java - MaterialAnimatedSwitch 保存状态
- javascript - 如何在正在测试的父对象中模拟子函数的输出?
- facebook - Facebook 与自定义图像单页应用程序共享
- javascript - .each() 将太多项目推送到数组
- azure - Azure MySQL数据库错误客户端和服务器无法通信,因为它们没有通用算法
- c++ - 空 grpc 客户端通道
- flutter - Flutter:跟踪应用打开的次数