Basi dei Channel: send, receive e close
Crei channel, invii e riceva valori e li chiuda correttamente.
Basi dei Channel: send, receive e close è una lezione Kotlin Academy gratuita su CoddyKit. Questa è la lezione 1 di 4. Puoi leggere la lezione completa qui gratuitamente — poi esercitati direttamente nel browser con un editor di codice integrato e un tutor IA disponibile 24/7. Fa parte del percorso di apprendimento Kotlin Academy, e i tuoi progressi si sincronizzano tra il web e l'app CoddyKit. Il corso Kotlin Academy include 4 lezioni in totale.
Che cos'è un canale?
Un Channel è una primitiva delle coroutine per comunicare tra coroutine: è simile a una coda bloccante, ma sospende invece di bloccare. Lo si può immaginare come un tubo: da un lato si invia, dall'altro si riceve.
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 e receive
send(value) sospende l'esecuzione finché il ricevitore non è pronto. receive() sospende l'esecuzione finché non è disponibile un valore.
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")
}Chiusura di un canale
channel.close() segnala che non verranno inviati altri valori. I ricevitori ottengono i valori ancora presenti nel buffer, dopodiché il ciclo for termina.
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
Controlli lo stato del canale con isClosedForSend (non è più possibile inviare valori) e isClosedForReceive (tutti i valori sono stati consumati).
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}")
}Builder produce
produce { } è un builder di coroutine che crea una coroutine produttrice e restituisce un ReceiveChannel. Il canale si chiude automaticamente al termine del blocco.
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
}Estensione consumeEach
consumeEach { } scorre un canale e lo annulla se il blocco genera un'eccezione, evitando perdite di risorse.
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 e trySend
Alternative non sospensive: trySend / tryReceive restituiscono immediatamente un ChannelResult senza sospendere l'esecuzione.
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: più consumatori
Più coroutine possono ricevere dallo stesso canale, distribuendo il lavoro: è un pattern 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")
}
}
}
}Fan-in: più produttori
Più coroutine possono inviare valori allo stesso canale, unificando i relativi output: è un pattern 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()
}
}Pattern pipeline
Colleghi i canali in una pipeline in cui ogni fase legge da un canale e scrive in un altro: è ideale per i flussi di elaborazione dei dati.
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()
}Canale e Flow a confronto
I canali sono hot e mantengono lo stato: esistono indipendentemente dal consumo. I Flow sono cold e dichiarativi: vengono riavviati a ogni raccolta. Preferisca Flow per i flussi di dati e utilizzi Channel per la comunicazione tra produttori e consumatori.
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") }Controllo rapido
Che cosa succede quando si chiama channel.close()?
Riepilogo
send e receive sospendono l'esecuzione finché l'altra parte non è pronta. close() segnala il completamento. Utilizzi produce per i produttori che si chiudono automaticamente, consumeEach per un'iterazione sicura e i canali per i pattern fan-out/fan-in.
Domande Frequenti
La lezione «Basi dei Channel: send, receive e close» è gratuita?
Sì — il testo completo di «Basi dei Channel: send, receive e close» è gratuito qui sul web. Per esercitarvi in modo interattivo (un editor di codice integrato e un tutor IA 24/7) e sbloccare il resto del corso Kotlin Academy, passa a CoddyKit PRO. Il corso Kotlin Academy include 4 lezioni in totale.
Cosa imparerò in «Basi dei Channel: send, receive e close»?
Crei channel, invii e riceva valori e li chiuda correttamente. Eserciti Kotlin Academy con codice pratico che esegui direttamente nel browser, e un tutor IA 24/7 risponde alle tue domande mentre lavori sulla lezione.
Ho bisogno di esperienza per iniziare Kotlin Academy?
Non è richiesta alcuna esperienza precedente. Kotlin Academy su CoddyKit è strutturato per principianti e studenti avanzati, quindi puoi iniziare da qui o dall'inizio e procedere al tuo ritmo. Questa è la lezione 1 di 4.
Quanto tempo richiede la lezione «Basi dei Channel: send, receive e close»?
La maggior parte delle lezioni CoddyKit richiede circa 5–10 minuti. Ogni lezione è breve e interattiva, quindi fai progressi costanti e riprendi esattamente da dove hai lasciato su web e app.
Posso scrivere ed eseguire codice in questa lezione Kotlin Academy?
Sì. Ogni lezione Kotlin Academy include un editor di codice integrato, quindi scrivi ed esegui codice reale direttamente nel tuo browser e ricevi feedback istantaneo dall'IA — nessuna configurazione locale necessaria.
Tutte le lezioni di questo corso
- Basi dei Channel: send, receive e close
- Tipi di Channel: Rendezvous, Buffered, Conflated, Unlimited
- Mutex e Semaphore per lo stato condiviso
- Actor e gestione strutturata dello stato