Будет ли переключение потока при запуске бесконечного цикла внутри корутины

Ответ

Бесконечный цикл внутри корутины не приведёт к автоматическому переключению потока. Корунтина выполняется в том же потоке, в котором была запущена, если явно не указан другой диспетчер.

Пример:

lifecycleScope.launch(Dispatchers.Default) {
    while (true) { // Блокирует поток Default dispatcher
        // Долгие вычисления
    }
}

Чтобы избежать блокировки потока:

  1. Используйте yield() для добровольной отдачи потока
  2. Разбивайте работу на части
  3. Используйте withContext(Dispatchers.IO) для CPU-intensive задач

Важно: бесконечные циклы в UI-потоке приведут к ANR!

Ответ 18+ 🔞

Да ты посмотри, какой подвох-то интересный! Чувак, ты думаешь, запустил корутину — и всё, она там сама по себе летает, как та мартышлюшка на банане? Хуй там! Если ты в неё воткнёшь бесконечный цикл, то она так и будет сидеть, ебать копать, в одном потоке, пока не накроется медным тазом.

Вот смотри, примерчик, тут всё ясно как божий день:

lifecycleScope.launch(Dispatchers.Default) {
    while (true) { // Этот уёбок намертво заблокирует поток Default dispatcher
        // Тут какие-то долгие вычисления, ебать колотить
    }
}

Представляешь? Ты запустил это дело на Dispatchers.Default, думая, что оно фоновое. А этот while (true) — он же, блядь, бесконечный! Он не отдаст управление, пока сам не закончится. А он никогда не закончится, ёпта! Вот и получается, что один из потоков в этом самом диспетчере просто встал колом, как хуй с горы. И другие задачи туда уже не пролезут, очередь будет копиться — терпения ноль ебать!

Так что же делать, спросишь ты? А выходы есть, не ссы:

  1. yield() — наш маленький друг. Периодически вставляй эту штуку в цикл. Типа «на, братан, поток, отдохни, я пока подожду». Корунтина добровольно сделает паузу и даст другим задачам шанс.
  2. Не жри слона целиком. Разбивай свою долгую работу на куски. Сделал кусок — проверил, не пора ли остановиться — сделал следующий. Не надо пытаться всё посчитать за один присест.
  3. Правильный инструмент для правильной работы. Если у тебя там реально тяжёлые вычисления, которые жрут процессор, то не мучай Default. Бери withContext(Dispatchers.IO) и делай там, где это предназначено.

И главное, запомни раз и навсегда, как «Отче наш»: если ты такой умный и сунешь бесконечный цикл прямо в UI-поток (ну, через lifecycleScope.launch без диспетчера), то приложение твоё просто зависнет. Буквально. Пользователь тыкнет на экран, а оно — ни хуя себе! — не реагирует. И через несколько секунд ему вылезет ANR, и он пойдёт тебе в ревью единицу ставить. Вот тебе и вся хитрая жопа с корутинами.

Короче, думай головой, э бошка! Асинхронность — это сила, но и ею можно так въебаться, что мало не покажется.