我正在尝试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函数写入本地文件,某些操作会失败,因为该文件可能已被另一个写入操作锁定了?
答案 0 :(得分:1)
这里的问题是List
实现可能不是线程安全的:如果两个不同的线程尝试同时更新它,则不能保证正确的操作。
(这种问题是有害的,因为它在大多数情况下都可以正常工作,但是在某些时候会失败,通常是在负载很重的情况下。)
我不知道是否有任何高性能的线程安全List
实现。
一种选择是采用普通选项,然后将其放入线程安全的包装器中。只要您仅通过该包装访问它,它将强制执行线程安全性(通过使用同步来序列化访问,强制调用者进行阻塞,直到轮到他们为止)。例如:
val list = java.util.Collections.synchronizedList(mutableListOf<String>())
另一种方法是使用一种专用的线程安全List
实现,例如CopyOnWriteArrayList
。 (或者,如果您只需要迭代而不是完整的List
实现,则有ConcurrentLinkedQueue
。)
(对于Map
来说情况会更好; JRE具有ConcurrentHashMap
,它是线程安全的,但具有高性能,并且大多数方法都不会阻塞。)
(我不知道File.appendText()
是否是线程安全的。我认为操作系统通常在文件级别提供这种安全性,但是我不知道这在这里是否适用。)< / p>