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

ชนิดของ Channel: Rendezvous, Buffered, Conflated, Unlimited

เลือกชนิด channel ให้เหมาะกับรูปแบบการสื่อสาร

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

ตัวสร้างแชนเนล

สร้างแชนเนลด้วย Channel<T>(capacity) ความจุจะกำหนดลักษณะการบัฟเฟอร์และการพักการทำงาน

import kotlinx.coroutines.channels.Channel
val rendezvous = Channel<Int>()              // capacity 0
val buffered   = Channel<Int>(64)            // capacity 64
val unlimited  = Channel<Int>(Channel.UNLIMITED)
val conflated  = Channel<Int>(Channel.CONFLATED)
fun main() { println("Channel types created") }

แชนเนล Rendezvous (capacity=0)

แชนเนลเริ่มต้น send จะพักการทำงานจนกว่าผู้รับจะพร้อม และ receive จะพักการทำงานจนกว่าผู้ส่งจะส่งข้อมูล ทั้งสองฝ่ายจะมาพบกันที่จุดเดียวกัน

import kotlinx.coroutines.*
import kotlinx.coroutines.channels.*
fun main() = runBlocking {
    val ch = Channel<Int>() // rendezvous
    launch {
        println("Sending...")
        ch.send(1)  // suspends until receiver is ready
        println("Sent")
    }
    delay(100)
    println("Receiving...")
    println(ch.receive())
}

แชนเนลแบบมีบัฟเฟอร์

แชนเนลแบบมีบัฟเฟอร์อนุญาตให้ผู้ส่งทำงานต่อได้โดยไม่ต้องรอจนกว่าบัฟเฟอร์จะเต็ม เมื่อเต็มแล้ว send จะพักการทำงาน

import kotlinx.coroutines.*
import kotlinx.coroutines.channels.*
fun main() = runBlocking {
    val ch = Channel<Int>(3) // buffer of 3
    launch {
        repeat(3) {
            println("Sending $it")
            ch.send(it) // does not suspend until buffer full
        }
        ch.close()
    }
    delay(500)
    for (v in ch) println("Got $v")
}

Channel.BUFFERED

Channel.BUFFERED ใช้ความจุเริ่มต้น 64 ซึ่งเทียบเท่ากับ Channel(64)

import kotlinx.coroutines.channels.Channel
import kotlinx.coroutines.*
fun main() = runBlocking {
    val ch = Channel<String>(Channel.BUFFERED)
    println("Default buffer capacity is implementation-defined (~64)")
    ch.close()
}

แชนเนลไม่จำกัด

Channel.UNLIMITED จะไม่พักการทำงานของผู้ส่ง แต่จะบัฟเฟอร์ค่าทั้งหมด โปรดใช้อย่างระมัดระวัง เนื่องจากหน่วยความจำอาจเพิ่มขึ้นโดยไม่จำกัด

import kotlinx.coroutines.*
import kotlinx.coroutines.channels.*
fun main() = runBlocking {
    val ch = Channel<Int>(Channel.UNLIMITED)
    launch {
        repeat(1000) { ch.send(it) } // never suspends
        ch.close()
    }
    var sum = 0
    for (v in ch) sum += v
    println("Sum: $sum")
}

แชนเนลแบบรวมค่า

Channel.CONFLATED เก็บไว้เฉพาะค่าล่าสุด หากมีค่าใหม่มาถึงก่อนที่จะรับค่าก่อนหน้า ค่าก่อนหน้าจะถูกทิ้ง

import kotlinx.coroutines.*
import kotlinx.coroutines.channels.*
fun main() = runBlocking {
    val ch = Channel<Int>(Channel.CONFLATED)
    launch {
        repeat(5) { ch.send(it) } // 0..4 sent rapidly
        ch.close()
    }
    delay(50) // let all sends happen
    println("Received: ${ch.tryReceive().getOrNull()}") // likely 4 (last)
}

จังหวะการทำงานของ RENDEZVOUS กับ BUFFERED

Rendezvous ทำให้ผู้ผลิตและผู้ใช้ทำงานประสานกัน ส่วน Buffered อนุญาตให้ผู้ผลิตทำงานนำหน้า จึงแยกจังหวะการทำงานของทั้งสองฝ่ายออกจากกัน

import kotlinx.coroutines.*
import kotlinx.coroutines.channels.*
fun main() = runBlocking {
    val ch = Channel<Int>(Channel.BUFFERED)
    val t = System.currentTimeMillis()
    launch {
        repeat(5) { ch.send(it) } // fast — doesn't wait
        ch.close()
    }
    for (v in ch) { delay(100); println("$v at ${System.currentTimeMillis()-t}ms") }
}

กลยุทธ์ onBufferOverflow

ด้วย Channel(capacity, onBufferOverflow) คุณสามารถเลือกสิ่งที่จะเกิดขึ้นเมื่อบัฟเฟอร์เต็มได้ ได้แก่ SUSPEND ซึ่งเป็นค่าเริ่มต้น, DROP_OLDEST หรือ DROP_LATEST

import kotlinx.coroutines.*
import kotlinx.coroutines.channels.*
fun main() = runBlocking {
    val ch = Channel<Int>(2, BufferOverflow.DROP_OLDEST)
    launch {
        repeat(5) { ch.trySend(it) } // 0,1,2,3,4 — buffer keeps newest 2
        ch.close()
    }
    for (v in ch) println(v) // likely 3 4
}

การเลือกชนิดแชนเนล

แนวทางการตัดสินใจ: ใช้ Rendezvous เพื่อการประสานงานที่แน่นหนา ใช้ Buffered เพื่อเพิ่มอัตราการประมวลผล ใช้ Conflated เพื่อเก็บเฉพาะค่าล่าสุด เช่น สถานะส่วนติดต่อผู้ใช้ และใช้ Unlimited สำหรับการบันทึกเหตุการณ์ที่ไม่ยอมให้ข้อมูลสูญหาย

import kotlinx.coroutines.channels.Channel
// Use cases:
// RENDEZVOUS  — handshake between producer and consumer
// BUFFERED    — decouple I/O-heavy producer from slow consumer
// CONFLATED   — UI updates (only latest matters)
// UNLIMITED   — audit log (never drop)
fun main() { println("Choose based on your loss tolerance and timing needs") }

แชนเนลใน select

select ช่วยให้รอแชนเนลหลายตัวพร้อมกันได้ โดยเลือกแชนเนลแรกที่พร้อม

import kotlinx.coroutines.*
import kotlinx.coroutines.channels.*
import kotlinx.coroutines.selects.*
fun main() = runBlocking {
    val a = produce { delay(100); send("from a") }
    val b = produce { delay(50);  send("from b") }
    val result = select<String> {
        a.onReceive { it }
        b.onReceive { it }
    }
    println(result) // "from b"
    coroutineContext.cancelChildren()
}

แชนเนลตัวจับเวลา

ticker(delay) สร้างแชนเนลที่ส่งค่า Unit ทุก ๆ delay มิลลิวินาที เหมาะสำหรับการสำรวจข้อมูลซ้ำเป็นระยะ

import kotlinx.coroutines.*
import kotlinx.coroutines.channels.*
fun main() = runBlocking {
    val ticker = ticker(delayMillis = 100, initialDelayMillis = 0)
    var count = 0
    for (tick in ticker) {
        println("Tick ${++count}")
        if (count == 3) { ticker.cancel(); break }
    }
}

ตรวจสอบความเข้าใจอย่างรวดเร็ว

แชนเนลชนิดใดเก็บไว้เฉพาะค่าล่าสุด

สรุปทบทวน

Rendezvous: ทำงานประสานกันโดยไม่มีบัฟเฟอร์ Buffered: แยกจังหวะการทำงาน Conflated: เก็บเฉพาะค่าล่าสุดและทิ้งค่าเก่า Unlimited: ไม่พักการทำงานของผู้ส่ง เลือกใช้ตามระดับการยอมรับข้อมูลสูญหายและความต้องการด้านอัตราการประมวลผล

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

บทเรียน “ชนิดของ Channel: Rendezvous, Buffered, Conflated, Unlimited” ฟรีหรือไม่

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

คุณจะเรียนรู้อะไรในบทเรียน “ชนิดของ Channel: Rendezvous, Buffered, Conflated, Unlimited”

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

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

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

บทเรียน “ชนิดของ Channel: Rendezvous, Buffered, Conflated, Unlimited” ใช้เวลานานแค่ไหน

บทเรียน 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