Podstawy Channel: send, receive i close
Twórz kanały, wysyłaj i odbieraj wartości oraz poprawnie je zamykaj.
Podstawy Channel: send, receive i close to bezpłatna lekcja Kotlin Academy na CoddyKit. To lekcja 1 z 4. Możesz przeczytać całą lekcję poniżej za darmo — a potem ćwiczyć ją interaktywnie w przeglądarce z wbudowanym edytorem kodu i tutorem AI dostępnym 24/7. To część ścieżki edukacyjnej Kotlin Academy, a Twój postęp synchronizuje się między webem a aplikacją CoddyKit. Kurs Kotlin Academy zawiera 4 lekcji w sumie.
Czym jest kanał?
Channel to prymityw korutynowy służący do komunikacji między korutynami — przypomina blokującą kolejkę, ale zamiast blokować, zawiesza wykonanie. Można myśleć o nim jak o rurze: jedna strona wysyła, a druga odbiera.
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 i receive
send(value) zawiesza wykonanie do momentu, gdy odbiorca będzie gotowy. receive() zawiesza wykonanie do momentu, gdy wartość będzie dostępna.
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")
}Zamykanie kanału
channel.close() sygnalizuje, że nie zostaną wysłane już żadne wartości. Odbiorcy otrzymują pozostałe wartości z bufora, po czym pętla for się kończy.
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
Stan kanału można sprawdzić za pomocą isClosedForSend (wysyłanie kolejnych wartości nie jest dozwolone) oraz isClosedForReceive (wszystkie wartości zostały odebrane).
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}")
}Konstruktor produce
produce { } to konstruktor korutyny, który tworzy korutynę producenta i zwraca ReceiveChannel. Kanał zamyka się automatycznie po zakończeniu bloku.
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
}Rozszerzenie consumeEach
consumeEach { } iteruje po kanale i anuluje go, gdy blok zgłosi wyjątek, zapobiegając wyciekom zasobów.
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 i trySend
Wersje niewymagające zawieszenia: trySend / tryReceive natychmiast zwracają ChannelResult, nie zawieszając wykonania.
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()}")
}Rozdzielanie: wielu konsumentów
Wiele korutyn może odbierać dane z tego samego kanału, rozdzielając między siebie pracę — jest to wzorzec fan-out.
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")
}
}
}
}Scalanie: wielu producentów
Wiele korutyn może wysyłać dane do tego samego kanału, łącząc swoje wyniki — jest to wzorzec fan-in.
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()
}
}Wzorzec potoku
Należy połączyć kanały w potok, w którym każdy etap odczytuje dane z jednego kanału i zapisuje je do kolejnego — doskonale sprawdza się to w potokach przetwarzania danych.
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()
}Kanał a Flow
Kanały są gorące i stanowe — istnieją niezależnie od odbioru danych. Przepływy są zimne i deklaratywne — uruchamiają się ponownie przy każdym zbieraniu. Należy preferować Flow dla strumieni danych, a Channel stosować do komunikacji producent–konsument.
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") }Szybkie sprawdzenie
Co się dzieje po wywołaniu channel.close()?
Podsumowanie
send i receive zawieszają wykonanie do momentu, gdy druga strona będzie gotowa. close() sygnalizuje zakończenie. Należy używać produce dla producentów zamykających się automatycznie, consumeEach do bezpiecznej iteracji, a kanałów dla wzorców fan-out/fan-in.
Często zadawane pytania
Czy lekcja „Podstawy Channel: send, receive i close” jest bezpłatna?
Tak — pełny tekst „Podstawy Channel: send, receive i close” jest dostępny za darmo tutaj w sieci. Aby ćwiczyć ją interaktywnie (wbudowany edytor kodu i tutor AI dostępny 24/7) i odblokować resztę kursu Kotlin Academy, przejdź na CoddyKit PRO. Kurs Kotlin Academy zawiera 4 lekcji w sumie.
Co nauczysz się w „Podstawy Channel: send, receive i close”?
Twórz kanały, wysyłaj i odbieraj wartości oraz poprawnie je zamykaj. Ćwiczysz Kotlin Academy z praktycznym kodem, który uruchamiasz bezpośrednio w przeglądarce, a tutor AI dostępny 24/7 odpowiada na Twoje pytania podczas pracy nad lekcją.
Czy potrzebuję doświadczenia, aby zacząć Kotlin Academy?
Nie wymagamy żadnego doświadczenia. Kotlin Academy w CoddyKit jest strukturyzowany dla początkujących i zaawansowanych użytkowników, więc możesz zacząć tutaj lub od początku i uczyć się w swoim tempie. To lekcja 1 z 4.
Ile czasu zajmuje lekcja „Podstawy Channel: send, receive i close”?
Większość lekcji CoddyKit trwa około 5–10 minut. Każda lekcja to mały, interaktywny krok, dzięki czemu robisz systematyczne postępy i zawsze wracasz dokładnie do tego samego miejsca — na webie i w aplikacji.
Czy mogę pisać i uruchamiać kod w tej lekcji Kotlin Academy?
Tak. Każda lekcja Kotlin Academy zawiera wbudowany edytor kodu, więc piszesz i uruchamiasz prawdziwy kod bezpośrednio w przeglądarce i od razu otrzymujesz sprzężenie zwrotne od AI — bez konfiguracji na komputerze.
Wszystkie lekcje w tym kursie
- Podstawy Channel: send, receive i close
- Typy Channel: Rendezvous, Buffered, Conflated, Unlimited
- Mutex i Semaphore dla współdzielonego stanu
- Aktory i strukturalne zarządzanie stanem