Asynchrone Programmierung in Kotlin: Vollständiger Leitfaden in der Praxis

Online Python-Trainer für Anfänger

Lernen Sie Python einfach ohne theoretische Überlastung. Lösen Sie praktische Aufgaben mit automatischer Überprüfung und schreiben Sie Code direkt im Browser.

Kurs starten

Asynchrone Programmierung in Kotlin: Vollständiger Leitfaden in der Praxis



Moderne Anwendungen erfordern hohe Leistung und Reaktionsfähigkeit. Asynchrone Programmierung in Kotlin mit Hilfe von Coroutinen (coroutines) ist zum De-facto-Standard für die Arbeit mit Netzwerkanfragen, Datenbanken und Dateioperationen geworden. In diesem Leitfaden werden wir die grundlegenden Konzepte erläutern, praktische Beispiele zeigen und fertige Vorlagen für den Einsatz in Ihren Projekten bereitstellen.



1. Grundlagen der Coroutinen in Kotlin



Coroutinen sind leichtgewichtige Threads, die es ermöglichen, die Ausführung einer Funktion anzuhalten, ohne den Hauptthread zu blockieren. Im Gegensatz zu traditionellen Threads können Coroutinen jederzeit angehalten und später wieder fortgesetzt werden, was sie ideal für asynchrone Operationen macht.



1.1. Einbinden der Abhängigkeiten

Fügen Sie zunächst die Abhängigkeiten in Ihre build.gradle.kts ein:



dependencies {    implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.8.0")    implementation("org.jetbrains.kotlinx:kotlinx-coroutines-android:1.8.0") // für Android}


1.2. Erste Coroutine

Erstellen wir eine einfache Coroutine mit runBlocking – einer Brücke zwischen der synchronen und der asynchronen Welt:



import kotlinx.coroutines.*

fun main() = runBlocking { launch { delay(1000L) // nicht-blockierende Verzögerung println("Welt!") } println("Hallo,") delay(2000L) // warten auf Beendigung der Coroutine}


In diesem Beispiel startet launch eine neue Coroutine, und delay ist eine anhaltende Funktion (suspend), die den Thread nicht blockiert.



2. Suspend-Funktionen und strukturierte Nebenläufigkeit



2.1. Erstellen von Suspend-Funktionen

Jede Funktion, die angehalten werden kann, muss mit dem Modifikator suspend gekennzeichnet werden. Solche Funktionen können nur aus Coroutinen oder anderen Suspend-Funktionen aufgerufen werden:



suspend fun fetchUserData(userId: String): User {    delay(2000L) // Simulation einer Netzwerkanfrage    return User(userId, "Ivan Petrov")}

suspend fun fetchUserPosts(userId: String): List<Post> { delay(1500L) return listOf(Post("Überschrift 1"), Post("Überschrift 2"))}


2.2. Sequenzielle Ausführung

Standardmäßig werden Coroutinen innerhalb eines einzelnen launch sequenziell ausgeführt:



fun main() = runBlocking {    val time = measureTimeMillis {        val user = fetchUserData("123")        val posts = fetchUserPosts("123")        println("${user.name} hat ${posts.size} Beiträge")    }    println("Ausführungszeit: $time ms") // ~3500 ms}


2.3. Parallele Ausführung mit async/await

Für die parallele Ausführung verwenden Sie async und await:



fun main() = runBlocking {    val time = measureTimeMillis {        val user = async { fetchUserData("123") }        val posts = async { fetchUserPosts("123") }                println("${user.await().name} hat ${posts.await().size} Beiträge")    }    println("Ausführungszeit: $time ms") // ~2000 ms (parallel)}


3. Coroutinen-Dispatcher und Kontexte



Dispatcher legen fest, auf welchem Thread oder Thread-Pool die Coroutine ausgeführt wird. Die wichtigsten Dispatcher:



  • Dispatchers.Default – für CPU-intensive Aufgaben (Standard)
  • Dispatchers.IO – für Ein-/Ausgabeoperationen (Netzwerk, Dateien)
  • Dispatchers.Main – für den UI-Thread (Android, Swing)
  • Dispatchers.Unconfined – nicht an einen bestimmten Thread gebunden


3.1. Beispiel mit Dispatchers.IO

fun main() = runBlocking {    launch(Dispatchers.IO) {        // Netzwerkanfrage        val response = httpClient.get("https://api.example.com/data")        withContext(Di                

Blogs

Buchempfehlungen