Sobes.tech
Middle

Č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 suspend môž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áti Job.
    • 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.