Сферы только косвенно участвуют в наблюдаемых вами различиях.
GlobalScope
- это синглтон, который определяет свой собственный диспетчер, который равен Dispatchers.Default
.Он поддерживается пулом потоков.
coroutineScope
не определяет свой собственный диспетчер, поэтому вы наследуете его от вызывающего, в данном случае тот, который создан runBlocking
.Он использует единственный поток, для которого он вызывается.
Если вы замените coroutineScope
на withContext(Dispatchers.Default)
, вы получите те же тайминги.Фактически именно так следует написать это (вместо GlobalScope
), чтобы получить разумное поведение перед лицом возможных сбоев некоторых из одновременных задач.