Я был уверен что CoroutineDispatcher в JVM реализации использует пул потоков ThreadPoolExecutor из Java, но как всегда бывает, вроде во всем разобрался, а нет нифига, найдется что-то новое и в моем случае это CoroutineScheduler.
CoroutineScheduler - это своего рода аналогия ThreadPoolExecutor, которая хранит и переиспользует потоки, а также распределяет между ними задачи, на этой штуке как раз и построены Dispatchers.Default и Dispatchers.IO, рассмотрим ключевые моменты:1) Все потоки хранятся в одном массиве, как для
Dispatchers.IO, так и для Dispatchers.Default, поэтому в случае бездействия одного из диспатчеров потоки другого могут быть спокойно переиспользованы.2) Потоки создаются лениво, когда это надо, тут важный момент - количество потоков для
Dispatchers.Default будет ограничено количеством ядер процессора, а для Dispatchers.IO потоки будут создаваться пока не достигнут 64 штук (если в системном свойстве не указано другое значение). 3) Все потоки в
CoroutineScheduler представлены абстракцией Worker, у каждого Worker'а есть своя очередь задач, в качестве задачи выступает выполнение корутины, помимо очереди для отдельного Worker'а есть еще две глобальные очереди - одна для CPU задач, другая для IO задач.4) При выполнении задачи сначала проверяется на каком потоке она выполняется, если на одном из потоков
CoroutineScheduler'а то сразу ставится в очередь актуального Worker'а, в противном случае добавляется в глобальную очередь, откуда Worker'ы в дальнейшем ее заберут.5) Могут быть ситуации когда
Worker содержит пустую очередь задач, то есть полностью свободен, в таком случае он попытается украсть задачу либо из глобальных очередей CPU и IO, либо у других Worker'ов, это оптимизация для более эффективного распределения задач.Всем хорошего кода!