Ответ
Корутина — это легковесный поток, который может приостанавливать выполнение без блокировки основного потока. В отличие от потоков, корутины дешевле создавать и переключать. Они работают на основе механизма suspension (приостановки) и возобновления выполнения.
Ключевые особенности:
- Не блокируют поток, на котором выполняются
- Могут быть отменены
- Поддерживают structured concurrency (структурированный параллелизм)
Пример с Kotlin:
viewModelScope.launch {
val data = withContext(Dispatchers.IO) {
fetchDataFromNetwork() // suspend функция
}
updateUI(data)
}
Где:
viewModelScope— скоуп корутины (автоматическая отмена при очистке ViewModel)withContext— переключение между диспетчерами (IO для сетевых операций)suspendфункции — точки приостановки корутины
Ответ 18+ 🔞
А, корутины, ёпта! Ну это ж как такой хитрожопый работяга внутри твоего основного потока. Представь: у тебя есть один чувак (главный поток), который должен и пироги печь, и на гитаре бренчать. Если он начнёт тесто долго месить — музыка встанет. Так вот корутина — это не второй чувак, а такой волшебный способ нашего парня приостановить замес теста на полуслове, быстро переключиться, отыграть пару аккордов, а потом вернуться к тесту ровно на том же месте, где остановился. И всё это без десяти наёмных грузчиков (потоков), которым зарплату платить.
Ключевые плюшки, бля:
- Не блокируют поток. Это главное, ебать мои старые костыли! Пока одна корутина, например, ждёт ответа от сервера, поток не тупит, как баран на новые ворота, а может другие дела делать.
- Их можно отменить. Начал качать гигабайтную хуйню, пользователь передумал — хуй с горы, отменил задачу, и все ресурсы почистились. Красота!
- Structured concurrency. Это чтоб у тебя эти легковесные потоки-шалуны по всей памяти не разбегались, как тараканы. Они все в рамках скоупа живут, и если папа-скоуп (например, экран) умер, то все его корутины-дети автоматом накрылись медным тазом. Удобно, ёпта, мусора не остаётся.
Смотри, как в коде выглядит эта магия:
viewModelScope.launch { // Запускаем корутину в скоупе ViewModel
val data = withContext(Dispatchers.IO) { // Говорим: "Слушай, дружок, эту конкретную хуйню иди делай в фоне"
fetchDataFromNetwork() // suspend функция — тут корутина ПРИОСТАНОВИТСЯ и будет ждать
}
updateUI(data) // А как данные придут — ОП! — возобновимся тут и обновим интерфейс
}
Расшифровываю, что тут за пиздопроебибна:
viewModelScope— это как клетка для корутин. Пока жива ViewModel — корутины в ней бегают. Убили ViewModel (экран закрыли) — клетку сожгли вместе со всеми, кто внутри.withContext(Dispatchers.IO)— команда "смена декораций". Всё, что внутри этих скобок, выполнится не в главном потоке (где UI рисуется), а в пуле для долгих операций (сеть, база данных). Потом корутина сама вернётся обратно.suspendфункции — это и есть те самые точки приостановки. Как только корутина до такой функции доползла, она говорит: "Всё, я тут зависну, не трогайте меня, пока операция не выполнится". А поток в это время — свободен! Может другие корутины выполнять или UI обновлять. Гениально и просто, как два пальца об асфальт.