Представим некого Петю, который недавно начал изучать корутины:
Вот он создал свой первый СoroutineScope
val coroutineScope = CoroutineScope(Job())

Затем добавил launch
fun main() {
val coroutineScope = CoroutineScope(Job())
coroutineScope.launch {
println("my awesome coroutine")
}
}
Запускает все это в надежде увидеть:
my awesome coroutine
Process finished with exit code 0
а получает:
Process finished with exit code 0

Прочитав данную статью, Петя поймет несколько важных вещей по работе с корутинами. Они помогут как в разработке, так и в прохождении собеседований!
Перейдем к самому вопросу:
Что выведет данный код?
fun main() {
val coroutineScope = CoroutineScope(Job())
coroutineScope.launch {
delay(1000) //имитация какой-то работы. Просто ждем одну секунду
println("Зеленое измерение")
}
println("Красное измерение")
}
Ответ на вопрос. Не открывай раньше времени, подумай сначала сам
Если ты ответил:
Зеленое измерение
Красное измерение
Process finished with exit code 0
Поздравляю!

Твоя психика еще цела и невредима, но ответ неправильный :(
Выведется:
Красное измерение
Process finished with exit code 0

Если не знаешь, почему так, то переходи к объяснению ниже*
Объяснение. Открывай, когда узнал правильный ответ
Представь, что красная область внутри функции main() и зеленая область внутри launch — это д ва разных измерения.
Кстати, код внутри launch – это и есть "корутина". Далее я буду называть launch таким образом

Давай узнаем разницу между измерениями:
Красное — это основное измерение (основной поток программы)
Зеленое — измерение, где временные задержки (delay) и последовательность выполнения кода могут отличаться от основного потока программы (красного измерения)
При запуске функции main() сначала красное измерение начинает выполнение, в то время как корутины могут начать свою работу параллельно или после запуска красного
Что в итоге происходит в нашем коде:
Когда мы запускаем main(), основной поток выполняет println(“Красное измерение”), не дожидаясь delay() в корутине, и программа завершается с фразой Process finished with exit code 0
Но как напечатать сначала “Зеленое измерение”, а потом “Красное измерение"?
Нам нужно сказать программе: "подожди пока выполнится delay(1000), а только потом напечатай "красное измерение"
Для этих целей можем использовать функцию join()
Добавим ее:

join() приостанавливает красное измерение, пока зеленое не завершит delay()
Видим ошибку:

Нам предлагают добавить к функции main() слово suspend
suspend означает, что функция может приостановить свое выполнение
Обращу внимание на то, что приостанавливается функция main(), а корутина активна и выполняется

Итак, сейчас красное измерение будет приостановлено

Добавив join(), мы имеем:

А теперь вопрос на засыпку!
Представим, что нет возможности использовать join()
Как сделать так, чтобы снова выводилось:
Зеленое измерение
Красное измерение

Ответ на вопрос. Не открывай раньше времени, подумай сначала сам
Нужно перенести delay() в красное измерение
Теперь suspend main() не может пройти мимо delay() и дождется его выполнения
Что нужно запомнить:
suspend функции должны быть вызваны внутри корутин или других suspend функций
join() — это suspend функция. В нашем случае она приостанавливает другую suspend функцию (а именно main)
suspend функции выделены специальным значком

4. Корутины запускаются не мгновенно, на это требуется какое-то время
Еще небольшие задачки:
Как думаешь, что выведет этот код:
Ответ проверь в IDEA или напиши в комментарии :)


