这段代码是线程安全的吗?我需要一个同步块或类似的东西吗?source1和source2无尽的Kotlin流
viewModelScope.launch {
var listAll = mutableListOf<String>()
var list1 = mutableListOf<String>()
var list2 = mutableListOf<String>()
launch {
source1.getNames().collect { list ->
list1 = list
listAll = mutableListOf()
listAll.addAll(list1)
listAll.addAll(list2)
//then consume listAll as StateFlow or return another flow with emit(listAll)
}
}
launch {
source2.getNames().collect { list ->
list2 = list
listAll = mutableListOf()
listAll.addAll(list2)
listAll.addAll(list1)
//then consume listAll as StateFlow or return another flow with emit(listAll)
}
}
}
1条答案
按热度按时间f0ofjuux1#
此代码不是线程安全的。
但是,它是从
viewModelScope.launch
调用的,默认情况下,Dispatchers.Main
运行在Dispatchers.Main
上。因此,内部的launch
块将被顺序调用。这意味着,最终您将获得由第二个launch
块产生的结果。要实现异步行为,您需要使用
viewModelScope.launch(Dispatchers.Default)
。在这种情况下,您的代码可能会触发并发修改异常。要同步它,您可能需要使用Java的
Collections.synchronizedList
,它在一个线程对列表执行操作时阻塞列表,因此其他线程无法执行修改。或者使用
Mutex
手动执行同步。读取official Kotlin guide to shared mutable state
毕竟,我很难想象你会在现实生活中真正使用这些代码。你可能不需要异步行为,不使用两个启动块就可以了。或者你应该重新考虑你的设计,以避免需要手动同步两个协程。