Coroutines — klíčové pojmy, Job a Dispatchers v Kotlinu

Autor: IT Sectr Publikováno: 2026-03-16 Doba čtení: 8 min

Coroutines (korutiny) jsou lehká vlákna Kotlinu pro asynchronní programování dostupná prostřednictvím knihovny kotlinx.coroutines. Podle JetBrains Kotlin Documentation, 2026 umožňují Coroutines pozastavit provádění funkce bez blokování vlákna, na rozdíl od tradičních Thread. Korutiny běží na omezeném fondu vláken, což je činí tisíckrát lehčími než nativní vlákna. Kotlin Coroutines jsou plně integrovány s Android Jetpack, Retrofit, Room a dalšími populárními knihovnami ekosystému Android.

Hlavní body

  • Coroutines — lehká vlákna Kotlinu pro asynchronní kód bez blokování
  • Suspend funkce — funkce schopná pozastavit a obnovit se bez blokování vlákna
  • Dispatcher určuje fond vláken pro provádění korutiny
  • Job — deskriptor korutiny s podporou zrušení a sledování stavu
  • CoroutineScope spravuje životní cyklus korutin a jejich zrušení při dokončení

Co jsou korutiny Kotlinu

Coroutines (korutiny) jsou mechanismus asynchronního programování v Kotlinu, implementovaný v knihovně kotlinx.coroutines. Na rozdíl od vláken operačního systému nejsou korutiny vázány na konkrétní vlákno: mohou se pozastavit na jednom vlákně a obnovit na jiném. Jedno vlákno může provádět tisíce korutin a přepínat mezi nimi s minimální režií.

Korutiny se objevily v Kotlin 1.3 (2018) jako experimentální funkce a staly se stabilními v Kotlin 1.5 (2021). Coroutines řeší problém callback hell podobně jako async/await, ale nabízejí bohatší API: kanály (Channel), Flow, zpracování výjimek v hierarchii Job a přímou integraci s Android Lifecycle.

Podle JetBrains (2025) spotřebovává každá korutina přibližně 100 bajtů paměti oproti 1+ MB pro nativní vlákno. To umožňuje spouštět miliony korutin v jedné aplikaci bez rizika OutOfMemoryError. Právě lehkost korutin z nich dělá preferovaný nástroj pro asynchronnost v Androidu.

Jak korutiny fungují pod kapotou

Každá korutina Kotlinu je zkompilována do stavového automatu pomocí Continuation Passing Style (CPS). Kompilátor přidává skrytý parametr Continuation ke každé suspend funkci. Continuation obsahuje bod obnovení a všechny lokální proměnné. Když se korutina pozastaví, runtime uloží Continuation, a když se obnoví, obnoví jej na jakémkoli dostupném vlákně z fondu Dispatcher.

Suspend funkce: pozastavení a obnovení

suspend — klíčové slovo Kotlinu označující funkci jako pozastavitelnou. Takovou funkci lze volat pouze z jiné suspend funkce nebo z korutiny. Uvnitř suspend funkce lze volat další suspend funkce v libovolném pořadí a každý bod volání je potenciální bod pozastavení.

Mechanika je jednoduchá: když suspend funkce volá jinou suspend funkci, pozastaví se v tomto bodě a uvolní vlákno. Po dokončení volané funkce runtime pokračuje v provádění z uloženého místa. Tomu se říká cooperative cancellation — žádné vlákno není blokováno.

  • Pozastavení — korutina uvolní vlákno, aniž by jej blokovala
  • Obnovení — korutina pokračuje ze stejného místa, kde se pozastavila
  • Vlákno — korutina se může pozastavit na vlákně A a obnovit na vlákně B
  • Výjimky — zpracovávají se pomocí try/catch stejně jako v synchronním kódu

Důležité: suspend funkce není ve výchozím nastavení asynchronní. Pořadí provádění zůstává sekvenční, pokud se nepoužije launch nebo async. suspend pouze umožňuje funkci být pozastavena bez blokování vlákna a být součástí kontextu korutiny. Continuation Passing Style je kompilační model, ve kterém každá suspend funkce obdrží skrytý callback Continuation a kompilátor vygeneruje stavový automat pro správu pozastavení a obnovení.

CoroutineScope a Structured Concurrency

CoroutineScope je kontext definující životní cyklus korutin. Všechny korutiny musí být spuštěny uvnitř scope. Když je scope zrušen (např. při ukončení Activity), všechny jeho podřízené korutiny jsou automaticky zrušeny. To zabraňuje únikům úloh na pozadí. Android Jetpack poskytuje hotové scopes pro každou komponentu: viewModelScope pro ViewModel a lifecycleScope pro Activity a Fragment, které se automaticky ruší při zničení příslušné komponenty.

Structured Concurrency — princip zaručující, že korutina neskončí, dokud neskončí všechny její podřízené korutiny. Hierarchie Job tvoří strom: kořenová korutina vytváří parent job, podřízené vytvářejí child jobs. Zrušení parent job se šíří na všechny děti. Structured Concurrency je zásadní rozdíl mezi korutinami a vlákny.

ScopeKde se používáZrušení
GlobalScopePouze pro úlohy daemonNeruší se automaticky
viewModelScopeAndroid ViewModelPři čištění ViewModel
lifecycleScopeAndroid Activity/FragmentPři zničení lifecycle
coroutineScopeUvnitř suspend funkcePři zrušení parent job

SupervisorJob pro zpracování chyb

Běžný Job při chybě jedné podřízené korutiny ruší všechny siblings. SupervisorJob je výjimka: selhání jedné podřízené korutiny neovlivní ostatní. To je důležité, když několik nezávislých úloh běží paralelně a jedna může selhat, aniž by bylo nutné rušit ostatní.

Dispatchers a stavitelé korutin

Dispatchers určují, na kterých vláknech se korutiny provádějí. Dispatchers.Main — hlavní UI vlákno Androidu. Dispatchers.IO — fond pro blokující operace (síť, disk). Dispatchers.Default — pro úlohy náročné na CPU. Dispatchers.Unconfined — startuje v aktuálním vlákně, ale nezaručuje, že na něm zůstane. Správný výběr Dispatcher je kritický pro výkon: úloha IO na Default zablokuje fond pro výpočty, zatímco úloha CPU na IO vytvoří zbytečná vlákna.

withContext — funkce pro přepínání Dispatcher uvnitř korutiny. Například suspend funkce parsující JSON může přepnout na Dispatchers.Default během výpočtu a vrátit se na Dispatchers.Main pro aktualizaci UI. withContext je nejpoužívanější stavitel ve vývoji pro Android.

Tři hlavní stavitelé korutin

launch — spouští korutinu, vrací Job, nevrací výsledek (fire-and-forget). async — spouští korutinu, vrací Deferred, ze kterého lze získat výsledek pomocí await. runBlocking — blokuje aktuální vlákno pro provádění korutiny (pouze pro testy a main funkce). Výběr stavitele závisí na scénáři: launch je vhodný pro události a aktualizace, async pro úlohy s výsledkem, runBlocking pouze pro testy nebo vstupní body.

Příklady kódu s korutinami v Kotlinu

Podívejme se na tři praktické scénáře: základní korutina s launch, paralelní volání s async a zpracování chyb s SupervisorJob.

Spuštění korutiny s launch

viewModelScope.launch spouští korutinu v kontextu ViewModel. Při čištění ViewModel je korutina automaticky zrušena.

kotlin
class ProfileViewModel : ViewModel() {
    fun loadUser() {
        viewModelScope.launch(Dispatchers.IO) {
            val user = api.fetchUser()
            withContext(Dispatchers.Main) {
                showUser(user)
            }
        }
    }
}

Paralelní požadavky s async

coroutineScope s async spouští tři požadavky paralelně. Výsledky se shromažďují pomocí .await(). Pokud některý požadavek selže, všechny jsou zrušeny.

kotlin
suspend fun loadDashboard(): Dashboard = coroutineScope {
    val user = async { api.fetchUser() }
    val posts = async { api.fetchPosts() }
    val stats = async { api.fetchStats() }
    Dashboard(user.await(), posts.await(), stats.await())
}

Zpracování chyb s SupervisorJob

SupervisorJob umožňuje každé korutině dokončit se nezávisle. Chyba v jednom požadavku neruší ostatní.

kotlin
val scope = CoroutineScope(SupervisorJob() + Dispatchers.IO)
scope.launch {
    try { api.fetchUsers() } catch (e: Exception) { log(e) }
}
scope.launch {
    try { api.fetchPosts() } catch (e: Exception) { log(e) }
}

Korutiny vs vlákna: srovnání a scénáře

Vlákna (Thread) — primitiv operačního systému. Každé vlákno má vlastní zásobník (~1 MB) a vyžaduje systémové volání pro vytvoření a přepnutí. Korutiny — jazykový primitiv, nezávislý na OS. Používají Continuation k ukládání stavu a přepínají na úrovni runtime bez systémových volání.

  • Paměť — vlákno ~1 MB, korutina ~100 bajtů. Rozdíl 10 000krát
  • Vytvoření — vlákno ~1 µs syscall, korutina ~0.01 µs na úrovni JVM
  • Přepnutí — vlákno ~0.1 µs (syscall), korutina ~0.001 µs (continuation)
  • Maximum — tisíce vláken vs miliony korutin na zařízení
  • Zrušení — vlákno nelze zrušit zvenčí (zastaralé Thread.stop), korutinu lze pomocí Job.cancel()

Podle Google (2025) snižuje použití korutin místo vláken spotřebu paměti pro úlohy na pozadí v aplikacích pro Android o 90–95%. Všechny moderní knihovny pro Android (Retrofit, Room, WorkManager) mají vestavěnou podporu pro korutiny prostřednictvím suspend funkcí. Ktor (HTTP klientský framework JetBrains) je také plně postaven na korutinách a poskytuje suspend-funkce pro každý požadavek bez callback API. Room podporuje korutiny prostřednictvím suspend-funkcí v DAO, což umožňuje provádět databázové dotazy bez blokování hlavního vlákna.

Kdy použít vlákna místo korutin

Vlákna zůstávají nezbytná pro nativní kód přes JNI, blokující volání náročná na CPU bez časového omezení (renderování videa, simulace) a při integraci s knihovnami C. Pro všechno ostatní — korutiny.

Často kladené otázky

Čím se liší korutina od vlákna?

Korutina — pozastavitelná jednotka práce, která se provádí na existujícím vlákně. Vlákno je systémový prostředek s vlastním zásobníkem. Korutiny jsou tisíckrát lehčí než vlákna a neblokují prostředky při pozastavení.

Co je Dispatchers.IO a čím se liší od Default?

Dispatchers.IO je určen pro blokující I/O operace (síť, soubory) a v případě potřeby může vytvářet nová vlákna. Dispatchers.Default má fond pevné velikosti (počet jader CPU) pro výpočty náročné na CPU.

Jak zrušit spuštěnou korutinu?

Job.cancel() ruší korutinu a všechny její děti. Pro kontrolu zrušení uvnitř korutiny použijte ensureActive() — vyvolá CancellationException, pokud je korutina zrušena.

Lze použít korutiny s RxJava?

Ano — prostřednictvím knihovny kotlinx-coroutines-rx3. Poskytuje funkce awaitSingle, awaitFirst a další pro převod Observable/Single na suspend funkce a zpět pomocí flowable.

Co je Flow v korutinách?

Flow — studený asynchronní datový tok, obdoba RxJava Observable pro korutiny. Flow emituje hodnoty sekvenčně a končí výjimkou nebo úspěchem. Podporuje operátory map, filter, catch a další.

Shrnutí

  • Coroutines — lehká vlákna Kotlinu s pozastavením bez blokování přes Continuation Passing Style
  • suspend — klíčové slovo pro označení pozastavitelných funkcí
  • Dispatchers spravují fond vláken: Main, IO, Default v tomto pořadí
  • CoroutineScope váže životní cyklus korutin ke komponentě (Activity, ViewModel)
  • launch spouští korutinu bez výsledku, async/await — s výsledkem
  • Structured Concurrency zaručuje hierarchické rušení podřízených korutin
  • Korutiny vs vlákna — korutiny jsou 10 000krát lehčí a jsou standardem pro Android

Vyvineme mobilní aplikaci na klíč

IT Sectr vytváří aplikace pro iOS a Android pro startupy a podniky od roku 2017. Poradíme vám a navrhneme nejlepší řešení.

Prodiskutovat projekt

Přečtěte si také