Сначала обычно появятся 1 и 2 в неопределённом порядке, затем 3 и строка First Async Second Async. Гарантирован порядок await в итоговой строке, но не планирование Default-потоков.
Поведение runBlocking при работе с async‑корутинами
Сначала обычно появятся 1 и 2 в неопределённом порядке, затем 3 и строка First Async Second Async. Гарантирован порядок await в итоговой строке, но не планирование Default-потоков.
Короткий ответ
Что ответить на собеседовании
Подробный разбор
Ответ с пояснениями
Условие
Определите, какой вывод появится в консоли после выполнения следующей программы:
val coroutineContext = Job() + Dispatchers.Default
val mainScope = CoroutineScope(coroutineContext)
val first = mainScope.async {
println(1)
delay(400)
"First Async"
}
val second = mainScope.async {
println(2)
delay(100)
"Second Async"
}
runBlocking {
delay(300)
println(3)
println("${first.await()} ${second.await()}")
}
Ответ
Сначала обычно появятся 1 и 2 в неопределённом порядке, затем 3 и строка First Async Second Async. Гарантирован порядок await в итоговой строке, но не планирование Default-потоков.
Обе async запускаются до runBlocking и выполняются независимо в mainScope. second имеет меньшую задержку, но результат выводится после ожидания first, потому что выражение строки вычисляется слева направо. Число 3 печатается перед итоговой строкой. Миллисекундные задержки не гарантируют точное время запуска: при задержке планировщика даже относительное положение 3 и первых println нельзя считать строгим контрактом.
Источник: kotlinlang.org.