0Pricing
Kotlin Academy · บทเรียน

พื้นฐาน Channel: send, receive และ close

สร้าง channel ส่งและรับค่า และปิด channel อย่างถูกต้อง

พื้นฐาน Channel: send, receive และ close เป็นบทเรียน Kotlin Academy ฟรีบน CoddyKit นี่คือบทเรียนที่ 1 จากทั้งหมด 4 บทเรียน คุณสามารถอ่านบทเรียนทั้งหมดด้านล่างฟรี — จากนั้นลองปฏิบัติด้วยตัวคุณเองในเบราว์เซอร์พร้อมตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7 บทเรียนนี้เป็นส่วนหนึ่งของเส้นทางการเรียน Kotlin Academy และความก้าวหน้าของคุณจะซิงค์ข้ามเว็บและแอป CoddyKit คอร์ส Kotlin Academy มีบทเรียนทั้งหมด 4 บทเรียน

แชนเนลคืออะไร

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.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()}")
}

Fan-Out: ผู้ใช้หลายราย

โครูทีนหลายตัวสามารถรับข้อมูลจากแชนเนลเดียวกันเพื่อแบ่งงานกันได้ ซึ่งเป็นรูปแบบ 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: ผู้ผลิตหลายราย

โครูทีนหลายตัวสามารถส่งข้อมูลไปยังแชนเนลเดียวกันเพื่อรวมผลลัพธ์เข้าด้วยกัน ซึ่งเป็นรูปแบบ 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()
    }
}

รูปแบบไปป์ไลน์

เชื่อมแชนเนลเป็นไปป์ไลน์ โดยแต่ละขั้นอ่านข้อมูลจากแชนเนลหนึ่งและเขียนไปยังอีกแชนเนลหนึ่ง เหมาะอย่างยิ่งสำหรับเวิร์กโฟลว์การประมวลผลข้อมูล

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()
}

แชนเนลกับโฟลว์

แชนเนลเป็นแบบร้อนและมีสถานะ กล่าวคือมีอยู่โดยอิสระจากการใช้งาน ส่วนโฟลว์เป็นแบบเย็นและมีลักษณะประกาศ กล่าวคือจะเริ่มต้นใหม่ทุกครั้งที่มีการรวบรวม ควรเลือกใช้ Flow สำหรับกระแสข้อมูล และใช้แชนเนลสำหรับการสื่อสารระหว่างผู้ผลิตกับผู้ใช้

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 สำหรับการวนซ้ำอย่างปลอดภัย และใช้แชนเนลสำหรับรูปแบบ fan-out/fan-in

คำถามที่พบบ่อย

บทเรียน “พื้นฐาน Channel: send, receive และ close” ฟรีหรือไม่

ใช่ — ข้อความเต็มของ “พื้นฐาน Channel: send, receive และ close” ฟรีให้อ่านที่นี่บนเว็บ เพื่อปฏิบัติแบบโต้ตอบ (ตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7) และปลดล็อคส่วนที่เหลือของคอร์ส Kotlin Academy ให้อัปเกรดเป็น CoddyKit PRO คอร์ส Kotlin Academy มีบทเรียนทั้งหมด 4 บทเรียน

คุณจะเรียนรู้อะไรในบทเรียน “พื้นฐาน Channel: send, receive และ close”

สร้าง channel ส่งและรับค่า และปิด channel อย่างถูกต้อง คุณปฏิบัติ Kotlin Academy ด้วยโค้ดที่ใช้งานได้จริงที่คุณเรียกใช้โดยตรงในเบราว์เซอร์ และติวเตอร์ AI ตลอด 24/7 ตอบคำถามของคุณขณะที่คุณไปผ่านบทเรียน

คุณต้องมีประสบการณ์ก่อนที่จะเริ่มเรียน Kotlin Academy หรือไม่

ไม่จำเป็นต้องมีประสบการณ์มาก่อน Kotlin Academy บน CoddyKit ออกแบบมาสำหรับผู้เริ่มต้นไปจนถึงผู้เรียนขั้นสูง คุณสามารถเริ่มต้นที่นี่หรือเริ่มจากตัวแรกและเรียนด้วยความเร็วของคุณเอง นี่คือบทเรียนที่ 1 จากทั้งหมด 4 บทเรียน

บทเรียน “พื้นฐาน Channel: send, receive และ close” ใช้เวลานานแค่ไหน

บทเรียน CoddyKit ส่วนใหญ่ใช้เวลาประมาณ 5–10 นาที แต่ละบทเรียนจึงสั้นและเป็นแบบโต้ตอบ คุณสามารถก้าวหน้าอย่างต่อเนื่องและกลับมาเรียนต่อจากตรงที่เพิ่งหยุดบนเว็บและแอปได้เลย

ฉันเขียนและรันโค้ดในบทเรียน Kotlin Academy นี้ได้ไหม

ได้ บทเรียน Kotlin Academy ทุกบทมีตัวแก้ไขโค้ดในตัว คุณจึงเขียนและรันโค้ดจริงได้เลยในเบราว์เซอร์ และได้รับข้อเสนอแนะจาก AI ในทันที — ไม่ต้องติดตั้งในเครื่องของคุณ

บทเรียนทั้งหมดในหลักสูตรนี้

  1. พื้นฐาน Channel: send, receive และ close
  2. ชนิดของ Channel: Rendezvous, Buffered, Conflated, Unlimited
  3. Mutex และ Semaphore สำหรับสถานะที่ใช้ร่วมกัน
  4. Actor และการจัดการสถานะแบบมีโครงสร้าง
← กลับไปที่ Kotlin Academy