kotlin - 在Kotlin中异步将项目添加到MutableList

标签 kotlin kotlin-coroutines

我正在尝试Kotlin协程。

说我有一个可变的 list :

val list = mutableListOf<String>()

我推出了50种couroutines,例如:
runBlocking {
    for (i in 1..50) {
        launch(Dispatchers.IO) {
            delay(1000)
            list.add(i.toString())
        }
    }
}
list.forEach { println(it) }

显然,尽管运行了“delay(1000)”,但这些操作仍将花费大约一秒钟,因为它们是异步运行的

这些是简单的操作,不会引起问题,但是如果我同时写很多大字符串怎么办,某些操作会失败吗?

使用appendText函数写入本地文件该怎么办,某些操作会失败,因为该文件可能被另一个写入操作锁定了吗?

最佳答案

这里的问题是List实现可能不是线程安全的:如果两个不同的线程尝试同时更新它,则不能保证正确的操作。

(这种问题是有害的,因为它在大多数情况下都可以正常工作,但在某些时候通常会在重负载下失败。)

我不知道是否有任何高性能的线程安全List实现。

一种选择是采用普通选项,然后将其放入线程安全的包装器中。只要您仅通过该包装访问它,它将强制执行线程安全性(通过使用同步来序列化访问,强制调用者进行阻塞,直到轮到他们为止)。例如:

val list = java.util.Collections.synchronizedList(mutableListOf<String>())

另一种方法是使用一种专用的线程安全List实现,例如CopyOnWriteArrayList。 (或者,如果您只需要迭代而不是完整的List实现,则可以使用ConcurrentLinkedQueue。)

(对于Map来说情况会更好; JRE的ConcurrentHashMap是线程安全的,但具有高性能,并且大多数方法都不会阻塞。)

(我不知道File.appendText()是否是线程安全的。我认为OS通常在文件级别提供这种安全性,但是我不知道这是否适用于此。)

关于kotlin - 在Kotlin中异步将项目添加到MutableList,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56792454/

相关文章:

kotlin - 如何在协程的计算代码中正确处理取消?

kotlin - 协程的执行顺序?

gradle - 将外部源文件添加到 kotlin 项目

java - 在 Kotlin 中将 Dp 转换为 Px - 这种转换永远不会成功

android - 更新至 Android Studio 3.0。收到 "Kotlin not configured"错误

android - 将 viewModelScope 与 LiveData 一起使用时出现问题

java - 如何在库初始化时设计与用户无关的错误状态?

postgresql - 使用 jOOQ 更新到 Postgres 表时返回更新行数

android - Laggy 懒惰专栏 Android Compose

android - CoroutineScope(job+Dispatchers.Main) 如何在主/UI 线程上运行?