ForkJoinPool и котлинские сопрограммы - PullRequest
1 голос
/ 13 марта 2019

Насколько я понимаю, по умолчанию, если вы запускаете Kotlin Coroutine через launch или async, он запустится через CommonPool (или если вы используете GlobalScope).И CommonPool - это ForkJoinPool, который по умолчанию находится в не асинхронном режиме, поэтому он выполняет задачи в порядке LIFO.Это выглядит как очень плохой выбор для чего-то вроде асинхронных приложений веб-сервера, где нам нужно честное планирование: мы не хотим, чтобы бедная присоска, которая сначала попала на наш веб-сервер, ждала всех звонков, которые пришли позже.

Однако сопрограммы Kotlin добавляют здесь дополнительную складку, поскольку в стандартной библиотеке Kotlin есть некоторый фрагмент кода, который будет организовывать выполнение этих сопрограмм (некоторые варианты стандартного цикла asyc select / epoll, насколько я понимаю).Так что, возможно, проблема с LIFO не имеет значения?

Я, конечно, мог бы провести некоторые эксперименты и / или перейти к коду в отладчике, чтобы посмотреть, как это работает, но я подозреваю, что у других есть тот же вопрос, и я готов поспорить с кем-то«просто знает» ответ ...

Ответы [ 2 ]

0 голосов
/ 17 марта 2019

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

0 голосов
/ 13 марта 2019

Это не должно быть проблемой, потому что ForkJoinPool на самом деле не LIFO.

То есть, это LIFO для одного потока в пуле, но именно здесь все становится интереснее с "частью кражи работы". Очередь задач для каждого потока имеет двойную связь. Итак, что такое LIFO для одного потока, это FIFO для другого потока, который стал свободным.

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

Кроме того, вы можете прочитать больше о asyncMode в документации, поскольку это не то, что "async": https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/ForkJoinPool.html

asyncMode - если true, устанавливает локальное планирование «первым пришел - первым вышел» режим для разветвленных задач, которые никогда не присоединяются. Этот режим может быть больше соответствующий по умолчанию режим локального стека в приложениях в какие рабочие потоки обрабатывают только асинхронные задачи в стиле событий. За значение по умолчанию, используйте false.

...