Какво е корутина в Kotlin и как работи?
sobes.tech AI
Отговор от AI
Корутина в Kotlin — това е лека единица за изпълнение, която позволява да се пише асинхронен неблокиращ код по-четлив и последователен начин. Тя е подобна на нишка (thread), но е много по-лека и може лесно да бъде създадена в голямо количество.
Основни компоненти и принципи на работа:
- Suspend Functions (Suspendable Functions): Функции, маркирани с ключовата дума
suspend, могат да спират (suspend) изпълнението си, без да блокират нишката, в която се изпълняват. Когато спряна функция завърши своята "очакваща" операция (например мрежов заявка), тя може да възобнови изпълнението от мястото, където е била спряна. - Context (Coroutine context): Комплект от елементи, управляващи поведението на корутината. В контекста влизат:
Job: Дескриптор на корутината, който позволява управление на нейния жизнен цикъл (отмяна, изчакване за завършване).CoroutineDispatcher: Определя нишката(ите), в които ще се изпълнява корутината. Позволява превключване между нишки.CoroutineName: Опционално име за отстраняване на грешки.CoroutineExceptionHandler: Обработчик на необработени изключения.
- Builders (Построители): Функции, които стартират изпълнението на корутини:
launch: Стартира нова корутина, без да връща резултат. ВръщаJob.async: Стартира нова корутина, която връща резултат (Deferred). За получаване на резултата се използва.await().runBlocking: Блокиращ строител, използван предимно за тестове или интеграция с блокиращ код.
Как работи това под капака:
Корутините не създават отделни нишки за всяка задача. Вместо това, при спиране на suspend функция, компилаторът генерира код, който запазва текущото състояние на изчисленията. Когато резултатът е наличен, корутината се възобновява на една от нишките, управлявани от CoroutineDispatcher. Това се постига чрез преобразуване на suspend функциите в асинхронни извиквания с продължения (continuation-passing style), което позволява на една нишка да изпълнява множество корутини, превключвайки между тях при спиране.
Пример:
import kotlinx.coroutines.*
fun main() = runBlocking { // Блокира текущата нишка до завършване на корутината вътре в runBlocking
println("Първо")
launch { // Стартираме нова корутина във фонов режим
delay(1000L) // Неблокираща забавяне за 1 секунда
println("След забавянето")
}
println("После") // Тази линия ще се изпълни преди завършването на launch корутината
}
Изходът от този код ще бъде:
Първо
После
След забавянето
Това демонстрира неблокиращия характер на launch и delay.