Что лучше использовать нить или сопрограмму в Kotlin? - PullRequest
2 голосов
/ 06 октября 2019

Я отправляю почту из приложения. Поскольку отправка почты занимает много времени и блокирует основной поток, я создаю новый поток и передаю задачу отправки почты новому потоку. Для большого количества одновременных запросов на отправку почты мне нужно создать много потоков. Но создание потока кажется медленным.

Мой вопрос: если я использую сопрограмму Kotlin, дает ли она лучшую производительность, чем поток?

Какие-то объяснения или подсказки весьма заметны.

Ответы [ 4 ]

3 голосов
/ 08 октября 2019

Вы должны почти всегда использовать сопрограммы для управления параллелизмом в Kotlin.

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

В Kotlin, когда вам требуется сопрограмма для запуска в другом или специальном потоке, вы используете «диспетчер», который в значительной степени эквивалентен потокубассейн. Dispatchers.IO предоставляется специально для выполнения длительных операций блокировки ввода-вывода, таких как отправка электронной почты.

Использовать его так же просто, как:

withContext(Dispatchers.IO) {
    sendEmail(...)
}
3 голосов
/ 08 октября 2019

Мой вопрос: если я использую сопрограмму Kotlin, дает ли она лучшую производительность, чем поток?

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

  • блокирующий API -> использовать пул потоков
  • неблокирующий (асинхронный) API -> использовать сопрограммы

Итак, если вы можете овладеть API асинхронной отправки почты, то обязательно используйте сопрограммы с ним. Но если вы застряли с блокирующим API, сопрограммы не принесут вам большой пользы. Они могут сделать более удобным перенос операции блокировки из потока пользовательского интерфейса, но механика будет одинаковой с сопрограммами или без них.

2 голосов
/ 06 октября 2019

TL; DR - всегда использовать сопрограммы при работе в Kotlin

Потоки занимают относительно большой объем памяти - около 1 МБ виртуальной памяти для каждого потока. Если вы создаете поток для каждой задачи, вы рискуете просто исчерпать память. Сопрограммы, для сравнения, относительно малы и занимают несколько килобайт памяти VM.

Создание нового потока происходит относительно медленно, так как он проходит через ОС. Операционная система ничего не знает о сопрограммах, поэтому порождение новой происходит относительно быстро.

По той же причине переключение контекста между потоками намного дороже, чем переключение контекста между приостановленными сопрограммами.

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

1 голос
/ 06 октября 2019

Очень обсуждаемый вопрос. Мой ответ основан на моем собственном опыте и нескольких веб-ссылках на известные ссылки.

Если вы пишете на Kotlin, я бы всегда использовал сопрограммы.

1. Производительность

baeldung.com

Создание слишком большого количества потоков может фактически привести к снижению производительности приложения в некоторых ситуациях;потоки - это объекты, которые накладывают накладные расходы во время размещения объектов и сборки мусора.

Чтобы преодолеть эти проблемы, Котлин представил новый способ написания асинхронного неблокирующего кода;сопрограмма.

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

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

Исходя из собственного опыта, я создаю приложение в своей компании для логистики, которое в какой-то момент времени выполнения имеет более 20 сопрограмм. работает параллельно - за 1,5 года у меня никогда не было проблем с «OutOMemory», «StackOverflow» или «замедлением работы основного приложения».

2. Удобство использования / сложность

По сравнению с потоками Java, использование сопрограмм Kotlin очень просто и не заставляет вас менять код. Последний пункт хорошо объяснен в этом видео.

Обычно работая в Java с потоками Java, люди создавали так много «процедур» или классов, чтобы повысить безопасность при многопоточности, что создаетогромные накладные расходы, о которых нужно знать, прежде чем делать действительно хорошую многопоточность. И это занимает много времени.

В Kotlin все просто: вам не нужны пулы потоков или твикинг кода, чтобы сделать его асинхронным - вы просто делаете это с помощью простого ключевого слова async.

...