Channelの基本:send、receive、close
Channelを作成し、値を送受信して、適切に閉じます。
「Channelの基本:send、receive、close」はCoddyKit上の無料Kotlin Academyレッスンです。 これはレッスン1/4です。 下記で完全なレッスンを無料で読むことができます。その後、ブラウザ内の組み込みコードエディタと24時間対応のAIチューターでハンズオン演習できます。 これはKotlin Academy学習パスの一部であり、ウェブとCoddyKitアプリ全体で進捗が同期されます。 Kotlin Academyコースには全4レッスンが含まれています。
Channelとは
Channelはコルーチン間の通信に使うプリミティブです。ブロッキングキューに似ていますが、待機時には一時停止します。片側が送信し、もう片側が受信するパイプだと考えてください。
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とreceive
send(value)は受信側の準備が整うまで一時停止します。receive()は値が利用可能になるまで一時停止します。
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")
}Channelを閉じる
channel.close()は、これ以上値が送信されないことを通知します。受信側は残っているバッファ内の値を受け取った後、forループを終了します。
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
isClosedForSend(これ以上送信できない)とisClosedForReceive(すべての値を消費済み)を使ってチャネルの状態を確認します。
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}")
}produceビルダー
produce { }はプロデューサーコルーチンを作成してReceiveChannelを返すコルーチンビルダーです。ブロックが終了するとチャネルは自動的に閉じられます。
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
}consumeEach拡張
consumeEach { }はチャネルを反復処理し、ブロックが例外をスローするとチャネルをキャンセルして、リソースリークを防ぎます。
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とtrySend
一時停止しない代替手段として、trySend/tryReceiveは一時停止せず、ChannelResultをすぐに返します。
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()}")
}ファンアウト:複数のコンシューマー
複数のコルーチンが同じチャネルから受信して作業を分担できます。これがファンアウトパターンです。
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")
}
}
}
}ファンイン:複数のプロデューサー
複数のコルーチンが同じチャネルに送信し、それぞれの出力を結合できます。これがファンインパターンです。
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()
}
}パイプラインパターン
チャネルをパイプラインとして連結し、各ステージが1つのチャネルから読み取り、別のチャネルに書き込むようにします。データ処理ワークフローに適しています。
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とFlowの違い
Channelはホットで状態を持ち、消費処理とは独立して存在します。Flowはコールドで宣言的であり、収集するたびに再開します。データストリームにはFlowを優先し、プロデューサーとコンシューマー間の通信にはChannelを使用します。
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") }クイックチェック
channel.close()を呼び出すとどうなりますか。
復習
sendとreceiveは、相手側の準備が整うまで一時停止します。close()は完了を通知します。自動的に閉じるプロデューサーにはproduce、安全な反復処理にはconsumeEachを使用し、ファンアウト/ファンインパターンにはチャネルを使用します。
AI チューターと学ぶ Kotlin — 無料
ブラウザでリアルコードを書いて実行し、24/7 の AI チューターから瞬時にサポートを受け、ウェブまたはアプリで続きから学習できます。
- コース
- 51
- レッスン
- 203
よくある質問
「Channelの基本:send、receive、close」レッスンは無料ですか?
はい。「Channelの基本:send、receive、close」の完全なテキストはこのウェブで無料で読めます。インタラクティブに演習し(組み込みコードエディタと24時間対応のAIチューター)、Kotlin Academyコースの残りをアンロックするには、CoddyKit PROにアップグレードしてください。 Kotlin Academyコースには全4レッスンが含まれています。
「Channelの基本:send、receive、close」で何を学びますか?
Channelを作成し、値を送受信して、適切に閉じます。 ブラウザで直接実行するハンズオンコードでKotlin Academyを演習し、24時間対応のAIチューターがレッスンを進める中での質問に答えます。
Kotlin Academyを始めるのに経験は必要ですか?
事前経験は必要ありません。CoddyKitのKotlin Academyは初級者から上級者向けに構成されているため、ここから始めるか最初から始めて、自分のペースで進むことができます。 これはレッスン1/4です。
「Channelの基本:send、receive、close」レッスンにはどのくらい時間がかかりますか?
ほとんどのCoddyKitレッスンは約5~10分かかります。各レッスンはコンパクトでインタラクティブなので、着実に進歩し、ウェブとアプリ全体で正確に前回の場所から再開できます。
このKotlin Academyレッスンでコードを書いて実行できますか?
はい。すべてのKotlin Academyレッスンに組み込みコードエディタが含まれているため、ブラウザでリアルコードを書いて実行し、即座のAIフィードバックを取得できます。ローカル設定は不要です。
このコースのすべてのレッスン
- Channelの基本:send、receive、close
- Channelの種類:Rendezvous、Buffered、Conflated、Unlimited
- 共有状態のためのMutexとSemaphore
- Actorと構造化された状態管理