Sobes.tech
Middle

Co je to coroutine v Kotlinu a jak funguje?

sobes.tech AI

Odpověď od AI

Korektina v Kotlinu je lehká jednotka vykonávání, která umožňuje psát asynchronní a neblokující kód srozumitelnějším a sekvenčním způsobem. Je podobná vláknu (thread), ale je mnohem lehčí a může být snadno vytvořena ve velkém množství.

Hlavní komponenty a principy fungování:

  • Funkce pozastavení (Suspend Functions): Funkce označené klíčovým slovem suspend, které mohou pozastavit své provádění, aniž by blokovaly vlákno, na kterém běží. Když pozastavená funkce dokončí operaci "čekání" (například síťový požadavek), může pokračovat tam, kde byla pozastavena.
  • Kontext (Coroutine context): Soubor prvků, které řídí chování korutiny. Zahrnuje:
    • Job: Popisovač korutiny, který umožňuje řídit její životní cyklus (zrušení, čekání na dokončení).
    • CoroutineDispatcher: Určuje vlákno nebo vlákna, na kterých bude korutina spuštěna. Umožňuje přepínání mezi vlákny.
    • CoroutineName: Volitelné jméno pro ladění.
    • CoroutineExceptionHandler: Zpracovatel nezpracovaných výjimek.
  • Stavitelé (Builders): Funkce, které spouštějí provádění korutin:
    • launch: Spustí novou korutinu, aniž by vrátila výsledek. Vrací Job.
    • async: Spustí novou korutinu, která vrací výsledek (Deferred). Výsledek lze získat pomocí .await().
    • runBlocking: Blokující stavitel, používaný hlavně pro testování nebo integraci s blokujícím kódem.

Jak to funguje na pozadí:

Korutiny nevytvářejí samostatná vlákna pro každý úkol. Místo toho, když je funkce suspend pozastavena, kompilátor generuje kód, který ukládá aktuální stav výpočtů. Když je výsledek dostupný, korutina je obnovena na jednom z vláken řízených CoroutineDispatcher. Toho se dosahuje přeměnou funkcí suspend na asynchronní volání s pokračováními, což umožňuje jednomu vláknu vykonávat mnoho korutin a přepínat mezi nimi při pozastavení.

Příklad:

import kotlinx.coroutines.*

fun main() = runBlocking { // Blokuje aktuální vlákno, dokud se nedokončí korutina uvnitř runBlocking
    println("Nejprve")

    launch { // Spouští novou korutinu na pozadí
        delay(1000L) // Neblokující zpoždění na 1 sekundu
        println("Po zpoždění")
    }

    println("Pak") // Tento řádek se provede před dokončením launch korutiny
}

Výstup tohoto kódu bude:

Nejprve
Pak
Po zpoždění

Toto demonstruje neblokující charakter launch a delay.