Čo je to coroutine v Kotlinu a ako funguje?
sobes.tech AI
Odpoveď od AI
Korektúra v Kotlin je ľahká jednotka vykonávania, ktorá umožňuje písať asynchrónny neblokujúci kód prehľadnejším a sekvenčnejším spôsobom. Je podobná vláknu (thread), ale je oveľa ľahšia a môže byť ľahko vytvorená vo veľkom množstve.
Hlavné komponenty a princípy práce:
- Suspend Functions (Suspendable Functions): Funkcie označené kľúčovým slovom
suspendmôžu pozastaviť (suspend) svoje vykonávanie, neblokujúc vlákno, v ktorom sa vykonávajú. Keď pozastavená funkcia ukončí svoju "čakajúcu" operáciu (napríklad sieťový dopyt), môže pokračovať vo vykonávaní od miesta, kde bola pozastavená. - Context (Coroutine context): Súbor prvkov, ktoré riadia správanie koretín. Do kontextu patrí:
Job: Dedič koretíny, ktorý umožňuje riadiť jej životný cyklus (zrušenie, čakanie na ukončenie).CoroutineDispatcher: Určuje vlákno(y), v ktorých bude koretína vykonávaná. Umožňuje prepínanie medzi vláknami.CoroutineName: Voliteľné meno pre ladenie.CoroutineExceptionHandler: Spracovateľ nezachytených výnimiek.
- Builders (Stavitelia): Funkcie, ktoré spúšťajú vykonávanie koretín:
launch: Spúšťa novú koretínu, bez návratu výsledku. VrátiJob.async: Spúšťa novú koretínu, ktorá vracia výsledok (Deferred). Na získanie výsledku sa používa.await().runBlocking: Blokujúci staviteľ, používaný hlavne na testovanie alebo integráciu s blokujúcim kódom.
Ako to funguje pod kapotou:
Koretíny nevytvárajú samostatné vlákna pre každú úlohu. Namiesto toho, pri pozastavení suspend funkcie, generuje kompilátor kód, ktorý uchováva aktuálny stav výpočtov. Keď je výsledok dostupný, koretína sa obnoví na jednom z vlákien riadených CoroutineDispatcher. To sa dosahuje transformáciou suspend funkcií na asynchrónne volania s pokračovaniami (continuation-passing style), čo umožňuje jednému vláknu vykonávať množstvo koretín, prepínajúc medzi nimi pri pozastavení.
Príklad:
import kotlinx.coroutines.*
fun main() = runBlocking { // Blokuje aktuálne vlákno do ukončenia koretíny vo vnútri runBlocking
println("Najskôr")
launch { // Spúšťame novú koretínu na pozadí
delay(1000L) // Neblokujúce oneskorenie na 1 sekundu
println("Po oneskorení")
}
println("Potom") // Táto línia sa vykoná pred ukončením launch koretíny
}
Výstup tohto kódu bude:
Najskôr
Potom
Po oneskorení
Toto demonštruje neblokujúci charakter launch a delay.