Выбор ответа Senior Корутины и structured concurrency спрашивают часто обновлено

Почему цикл не отменяется

Вопрос

Корутина выполняет цикл без вызова suspend-функций. Что произойдёт после job.cancel()?

val job = scope.launch(Dispatchers.Default) {
    var i = 0L
    while (i < 5_000_000_000L) { i++ }
}
job.cancel()

Попробуйте сами

Выберите вариант, и откроется разбор.

Показать ответ и разбор

Коротко

Правильный ответ: Цикл дойдёт до конца: отмена проверяется кооперативно. cancel() только переводит Job в состояние Cancelling.

Варианты ответа

  1. Цикл прервётся мгновенно, поток будет остановлен
  2. Будет брошен InterruptedException в потоке цикла
  3. Корутина перезапустится с начала цикла
  4. Цикл дойдёт до конца: отмена проверяется кооперативноправильный ответ

Разбор

cancel() только переводит Job в состояние Cancelling. Прервётся корутина в ближайшей точке приостановки, где suspend-функции из kotlinx.coroutines проверяют отмену и бросают CancellationException. Чисто вычислительный цикл этого не увидит, поэтому в нём проверяют isActive, вызывают ensureActive() или yield(). Поток при этом не прерывается, InterruptedException не бросается.

Ответьте сами, а не прочитайте

В тренажёре вопрос попадёт в повторения и вернётся, когда начнёт забываться. Плюс билеты с зачётом: 20 вопросов, не больше 2 ошибок.