Виртуальные потоки Java против сопрограмм Kotlin
Как виртуальные потоки Java 21 будут сравниваться с сопрограммами Kotlin?
При кодировании на Kotlin лучше ли отдавать предпочтение одному другому?
Это видео: Новая функция Java 21: виртуальные потоки #RoadTo21, похоже, не одобряет использование виртуальных потоков для задач, не связанных с вводом-выводом или неблокирующих.
Я создаю сопрограммы справа и слева даже для ресурсоемких задач в своем коде на Kotlin. Это уже не в порядке вещей?
2 ответа
Это уже не в порядке вещей? Все в порядке, виртуальные потоки Java не заменят сопрограммы Kotlin.
Есть презентация Романа Елизарова, в которой рассказывается об этой разнице.
Краткий итог презентации
Виртуальные потоки (Project Loom) хороши для
- Виртуальный поток по запросу
- Обновление существующего кода
Kotlin Coroutines хороши для
- Высококонкурентный код
- Системы, основанные на событиях
- Структурированный параллелизм и отмены
И, как упомянул @Slaw в комментарии, сопрограммы могут выполняться и в виртуальных потоках. Также сопрограммы можно использовать с Kotlin/JS и Kotlin/Native.
Из этого видео мы можем сказать, что Loom великолепен. Но это не замена сопрограмм Kotlin. Сопрограммы по-прежнему рекомендуется использовать при работе с параллельными процессами в Котлине. Чтобы сравнить их,
- Loom может повысить производительность приложений: он может запускать несколько виртуальных потоков, и блокировка виртуальных потоков обходится дешевле, чем блокировка обычных потоков.- Сопрограммы Kotlin навязчивы, потому что мы не можем вызывать функции приостановки в обычной функции, чего нельзя сказать о Loom.
- Структурированный параллелизм гораздо проще с сопрограммами Kotlin, чем с Loom.
- Взаимодействие между сопрограммами Kotlin и реактивным программированием проще, поскольку мы можем просто использовать потоки, чем между ткацким станком и реактивным программированием.
Подводя итог, можно сказать, что лучшее, что может предложить Loom, — это виртуальные потоки, которые могут повысить производительность, в то время как сопрограммы Kotlin могут предложить больше. Почему бы не использовать обе функции вместе?
Что ж, есть интересная концепция, представленная Москалой в его книге « Сопрограммы Kotlin: глубокое погружение ». Мы можем использовать Loom непосредственно в коде сопрограмм Kotlin и добиться большей производительности, сохраняя при этом структурированный параллелизм и все те интересные вещи, которые мы получаем в сопрограммах. Для этого мы используем виртуальные потоки для замены . Ниже приведен пример кода, использующего виртуальный поток.
val LoomDispatcher = Executors
.newVirtualThreadPerTaskExecutor()
.asCoroutineDispatcher()
val Dispatchers.Loom: CoroutineDispatcher
get() = LoomDispatcher
suspend fun main() = measureTimeMillis {
coroutineScope {
repeat(100_000) {
launch(Dispatchers.Loom) {
Thread.sleep(1000)
}
}
}
}.let(::println)
Поскольку в нем всего 64 потока, приведенный выше код займет более 26 минут, но мы можем использовать
suspend fun main() = measureTimeMillis {
val dispatcher = Dispatchers.IO
.limitedParallelism(100_000)
coroutineScope {
repeat(100_000) {
launch(dispatcher) {
Thread.sleep(1000)
}
}
}
}.let(::println)
Я лично не запускал код с виртуальными потоками, но в книге сказано, что его выполнение заняло чуть больше двух секунд (это удивительно, зная, что мы блокируем каждый из 100 000 потоков на 1 секунду), но второй выполнение кода заняло около 30 секунд.
Я бы сказал, что лучший способ повысить производительность кода и использовать некоторые интересные вещи, которые предлагают сопрограммы, — это использовать Loom в качестве замены