Добавление элементов в MutableList асинхронно в kotlin - PullRequest
0 голосов
/ 27 июня 2019

Я экспериментирую с сопрограммами Kotlin.

скажем, у меня есть изменяемый список:

val list = mutableListOf<String>()

, и я запустил 50 процедур, как это:

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

очевидно, что операции будут занимать около одной секунды, несмотря на «задержку (1000)», поскольку они выполняются асинхронно

. Это были простые операции, которые не вызовут проблем, но что, если я пишу многобольшие строки в то же время, если некоторые операции завершатся неудачно?

а как насчет записи в локальный файл с помощью функции appendText, некоторые операции завершатся неудачно, поскольку файл может быть заблокирован другой операцией записи?

1 Ответ

1 голос
/ 27 июня 2019

Проблема здесь в том, что реализация List, вероятно, не является поточно-ориентированной: она не гарантирует корректную работу, если два разных потока пытаются обновить ее одновременно.

(Подобные проблемы губительны, так как большую часть времени они будут работать нормально, но в какой-то момент произойдут сбои, обычно при большой нагрузке.)

Я не знаю, есть ли какие-нибудь высокопроизводительные поточно-безопасные List реализации.

Один из вариантов - взять нормальный и положить его в многопоточную оболочку; до тех пор, пока вы обращаетесь к нему только через эту оболочку, он будет обеспечивать безопасность потоков (используя синхронизацию для сериализации доступа, заставляя абонентов блокировать, пока они не получат свою очередь). Например:

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

Другой способ - использовать одну из специальных поточно-ориентированных реализаций List, например CopyOnWriteArrayList. (Или, если вам нужна только итерация, а не полная реализация List, есть ConcurrentLinkedQueue.)

(Все лучше на Map с; JRE имеет ConcurrentHashMap, который является поточно-ориентированным, но высокопроизводительным, и большинство методов не блокируют.)

(Я не знаю, является ли File.appendText() поточно-ориентированным или нет. Я думаю, что ОС обычно обеспечивает такую ​​безопасность на уровне файлов, но я не знаю, применимо ли это здесь.)

...