← Kembali ke kursus
Pelajaran kursus · Go
Pelajaran 27

Buffered channel

Channel dengan ruang tunggu agar pengiriman tidak langsung menunggu.

Pahami konsepnya

make(chan int, 3) membuat channel ber-buffer: ia bisa menampung tiga nilai sebelum pengiriman mulai menunggu. Selama ruang masih ada, ch <- v langsung selesai tanpa perlu penerima yang siap — seperti kotak pesan yang bisa diisi beberapa surat dulu.

Begitu buffer penuh, pengiriman berikutnya memblokir sampai ada yang menerima. Sebaliknya penerimaan pada buffer kosong juga menunggu. len(ch) melaporkan berapa nilai sedang menunggu dan cap(ch) ukuran buffernya.

Buffer mengubah watak sinkron channel menjadi semi-asinkron: kirim dan terima tidak wajib berpasangan saat itu juga. Manfaatnya melicinkan perbedaan kecepatan antar goroutine (producer cepat, consumer lambat), tapi jangan dijadikan alat menunda masalah — buffer terlalu besar hanya menyembunyikan kemacetan, bukan menyelesaikannya. Aturan praktis: mulai dari tanpa buffer, tambah buffer saat polanya jelas butuh.

Coba contoh kode

package main

import "fmt"

func main() {
    ch := make(chan int, 3)

    ch <- 1 // tidak menunggu: buffer masih kosong
    ch <- 2
    ch <- 3

    fmt.Println(len(ch), cap(ch)) // 3 3
    fmt.Println(<-ch)             // 1 (yang pertama masuk)
    fmt.Println(<-ch)             // 2
}

Tiga pengiriman berturut-turut berhasil tanpa satu pun penerima karena buffer berukuran 3. Penerimaan mengambil sesuai urutan masuk (FIFO) — 1 dulu, baru 2. Setelah ketiga nilai diterima, buffer kosong dan pengiriman keempat akan menunggu.

Buffer penuh memblokir

func main() {
    ch := make(chan int, 2)

    ch <- 1
    ch <- 2
    // ch <- 3 // deadlock! buffer penuh tanpa penerima

    fmt.Println(<-ch)
    fmt.Println(<-ch)
}

Baris ketiga yang dikomentari akan menghentikan program dengan fatal error: all goroutines are asleep — pengiriman ke buffer penuh menunggu selamanya karena tak ada penerima. Ukuran buffer adalah jumlah penyangga, bukan kapasitas tak terbatas.

Latihan singkat

Uji: isi buffer-5 dengan 1..5 lewat loop TANPA penerima, lalu kosongkan — harus mencetak `1 2 3 4 5` (satu angka per baris).