Kotlin Academy · Lektion

Grunderna i Channel: send, receive och close

Skapa channels, skicka och ta emot värden och stäng dem korrekt.

Lektion 1 av 413 steg

Grunderna i Channel: send, receive och close är en gratis lektion i Kotlin Academy på CoddyKit. Detta är lektion 1 av 4. Du kan läsa vilka 3 lektioner som helst i den här lärvägen kostnadsfritt i sin helhet – därefter låser CoddyKit PRO upp alla lektioner, plus praktisk övning med en inbyggd kodredigerare och en AI-lärare dygnet runt. Den ingår i lärvägen för Kotlin Academy, och Era framsteg synkroniseras mellan webben och CoddyKit-appen. Kursen i Kotlin Academy innehåller totalt 4 lektioner.

Vad är en Channel?

En Channel är en koroutinprimitiv för kommunikation mellan koroutiner — ungefär som en blockerande kö, men med suspendering. Tänk på den som ett rör: den ena sidan skickar och den andra tar emot.

import kotlinx.coroutines.*
import kotlinx.coroutines.channels.*
fun main() = runBlocking {
    val channel = Channel<Int>()
    launch {
        for (i in 1..5) channel.send(i)
        channel.close()
    }
    for (x in channel) println(x) // 1 2 3 4 5
}

send och receive

send(value) suspenderas tills mottagaren är redo. receive() suspenderas tills ett värde är tillgängligt.

import kotlinx.coroutines.*
import kotlinx.coroutines.channels.*
fun main() = runBlocking {
    val ch = Channel<String>()
    launch {
        ch.send("ping")
        println("sent")
    }
    val msg = ch.receive()
    println("received: $msg")
}

Stänga en Channel

channel.close() signalerar att inga fler värden kommer att skickas. Mottagarna får de återstående buffrade värdena, och därefter avslutas for-loopen.

import kotlinx.coroutines.*
import kotlinx.coroutines.channels.*
fun main() = runBlocking {
    val ch = Channel<Int>(3)
    launch {
        repeat(3) { ch.send(it) }
        ch.close()  // signal done
    }
    for (v in ch) println(v) // 0 1 2, then loop ends
    println("Channel consumed")
}

isClosedForSend / isClosedForReceive

Kontrollera kanalens tillstånd med isClosedForSend (inga fler sändningar tillåts) och isClosedForReceive (alla värden har tagits emot).

import kotlinx.coroutines.*
import kotlinx.coroutines.channels.*
fun main() = runBlocking {
    val ch = Channel<Int>()
    launch {
        ch.send(1)
        ch.close()
    }
    println(ch.receive())
    println("isClosedForReceive: ${ch.isClosedForReceive}")
}

Byggaren produce

produce { } är en koroutinbyggare som skapar en producentkoroutin och returnerar en ReceiveChannel. Kanalen stängs automatiskt när blocket avslutas.

import kotlinx.coroutines.*
import kotlinx.coroutines.channels.*
fun CoroutineScope.squares(n: Int) = produce<Int> {
    for (i in 1..n) send(i * i)
}
fun main() = runBlocking {
    val sq = squares(5)
    for (v in sq) println(v) // 1 4 9 16 25
}

Tillägget consumeEach

consumeEach { } itererar över en kanal och avbryter den om blocket kastar ett undantag, vilket förhindrar läckor.

import kotlinx.coroutines.*
import kotlinx.coroutines.channels.*
fun main() = runBlocking {
    val ch = produce<String> {
        send("a"); send("b"); send("c")
    }
    ch.consumeEach { println(it) }
}

tryReceive och trySend

Alternativ som inte suspenderas: trySend / tryReceive returnerar omedelbart ett ChannelResult utan att suspenderas.

import kotlinx.coroutines.*
import kotlinx.coroutines.channels.*
fun main() = runBlocking {
    val ch = Channel<Int>(1)
    val sendResult = ch.trySend(42)
    println("Sent: ${sendResult.isSuccess}")
    val recvResult = ch.tryReceive()
    println("Got: ${recvResult.getOrNull()}")
}

Fan-out: flera konsumenter

Flera koroutiner kan ta emot från samma kanal och fördela arbetet — ett fan-out-mönster.

import kotlinx.coroutines.*
import kotlinx.coroutines.channels.*
fun main() = runBlocking {
    val tasks = produce { repeat(6) { send(it) } }
    repeat(3) { worker ->
        launch {
            for (task in tasks) {
                println("Worker $worker: task $task")
            }
        }
    }
}

Fan-in: flera producenter

Flera koroutiner kan skicka till samma kanal och slå samman sina utdata — ett fan-in-mönster.

import kotlinx.coroutines.*
import kotlinx.coroutines.channels.*
fun main() = runBlocking {
    val results = Channel<String>()
    repeat(3) { i ->
        launch { results.send("result-$i") }
    }
    launch {
        repeat(3) { println(results.receive()) }
        results.close()
    }
}

Pipelinemönstret

Kedja kanaler till en pipeline där varje steg läser från en kanal och skriver till en annan — utmärkt för arbetsflöden för databearbetning.

import kotlinx.coroutines.*
import kotlinx.coroutines.channels.*
fun CoroutineScope.numbers() = produce { for (i in 1..5) send(i) }
fun CoroutineScope.doubled(input: ReceiveChannel<Int>) = produce { for (v in input) send(v * 2) }
fun main() = runBlocking {
    val nums = numbers()
    val doubled = doubled(nums)
    for (v in doubled) println(v) // 2 4 6 8 10
    coroutineContext.cancelChildren()
}

Channel jämfört med Flow

Kanaler är heta och tillståndsfulla — de existerar oberoende av konsumtionen. Flow är kalla och deklarativa — de startas om vid varje insamling. Föredra Flow för dataströmmar och använd Channel för producent-konsument-kommunikation.

import kotlinx.coroutines.*
import kotlinx.coroutines.channels.*
import kotlinx.coroutines.flow.*
// Flow (cold): each collect() re-runs the block
// Channel (hot): shared; multiple receivers share the same stream
fun main() = runBlocking { println("Flow = cold; Channel = hot") }

Snabbtest

Vad händer när ni anropar channel.close()?

Sammanfattning

send och receive suspenderas tills den andra sidan är redo. close() signalerar att körningen är klar. Använd produce för producenter som stänger sig själva, consumeEach för säker iteration och kanaler för fan-out- och fan-in-mönster.

Gratis att börja

Lär dig Kotlin med en AI-lärare – gratis

Skriv och kör riktig kod i webbläsaren, få omedelbar hjälp av en AI-lärare dygnet runt och fortsätt där du slutade – på webben eller i appen.

Kurser
51
Lektioner
203

Vanliga frågor

Är lektionen ”Grunderna i Channel: send, receive och close” gratis?

Ja – du kan läsa vilka 3 lektioner som helst i lärvägen Kotlin Academy, inklusive ”Grunderna i Channel: send, receive och close”, kostnadsfritt i sin helhet här på webben. Därefter låser CoddyKit PRO upp alla lektioner, plus interaktiv övning med en inbyggd kodredigerare och en AI-lärare dygnet runt. Kursen i Kotlin Academy innehåller totalt 4 lektioner.

Vad lär jag mig i ”Grunderna i Channel: send, receive och close”?

Skapa channels, skicka och ta emot värden och stäng dem korrekt. Ni övar på Kotlin Academy med praktisk kod som körs direkt i webbläsaren, medan en AI-handledare som är tillgänglig dygnet runt svarar på Era frågor under lektionen.

Behöver jag någon erfarenhet för att börja lära mig Kotlin Academy?

Du behöver inga förkunskaper. Utbildningen i Kotlin Academy på CoddyKit är upplagd för allt från nybörjare till avancerade elever, så att du kan börja här eller från början och gå fram i din egen takt. Detta är lektion 1 av 4.

Hur lång tid tar lektionen ”Grunderna i Channel: send, receive och close”?

De flesta CoddyKit-lektioner tar cirka 5–10 minuter. Varje lektion är kort och interaktiv, så att du gör stadiga framsteg och kan fortsätta precis där du slutade – på webben eller i appen.

Kan jag skriva och köra kod i den här Kotlin Academy-lektionen?

Ja. Varje Kotlin Academy-lektion innehåller en inbyggd kodredigerare, så att du kan skriva och köra riktig kod direkt i webbläsaren och få omedelbar AI-feedback – utan lokal installation.

Alla lektioner i den här kursen

  1. Grunderna i Channel: send, receive och close
  2. Channel-typer: Rendezvous, Buffered, Conflated, Unlimited
  3. Mutex och Semaphore för delat tillstånd
  4. Aktörer och strukturerad tillståndshantering
← Tillbaka till Kotlin Academy