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

时间:2019-06-27 13:45:37

标签: kotlin kotlin-coroutines

我正在尝试Kotlin协程。

说我有一个可变的列表:

val list = mutableListOf<String>()

我像这样推出了50种couroutine:

runBlocking {
    for (i in 1..50) {
        launch(Dispatchers.IO) {
            delay(1000)
            list.add(i.toString())
        }
    }
}
list.forEach { println(it) }

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

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

关于如何使用appendText函数写入本地文件,某些操作会失败,因为该文件可能已被另一个写入操作锁定了?

1 个答案:

答案 0 :(得分:1)

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

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

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

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

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

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

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

(我不知道File.appendText()是否是线程安全的。我认为操作系统通常在文件级别提供这种安全性,但是我不知道这在这里是否适用。)< / p>