Lompat ke konten Lompat ke sidebar Lompat ke footer

Golang Concurrency #7

Jika channel sudah ditutup, tetapi masih ada data yang belum dibaca, tidak akan terjadi error atau panic. Goroutine utama tetap bisa membaca sisa data yang sudah ada di dalam channel sebelum akhirnya loop berhenti.

Mari kita bahas mekanismenya lebih dalam:


1. Apa yang Terjadi Jika Channel Ditutup Sebelum Semua Data Dibaca?

Ketika sebuah channel ditutup:

  • Data yang sudah ada di dalam channel tetap bisa dibaca.
  • Pembacaan akan terus berjalan sampai channel kosong.
  • Setelah channel kosong dan ditutup, operasi pembacaan akan mengembalikan nilai default (zero value) dan loop for range akan otomatis berhenti.
  • Menutup channel tidak menghapus data yang sudah ada di dalamnya.

Contoh Eksperimen Sederhana:

package main import "fmt" func main() { ch := make(chan int, 3) // Channel buffered kapasitas 3 ch <- 1 ch <- 2 ch <- 3 close(ch) // Menutup channel setelah mengirim data for v := range ch { fmt.Println("Membaca:", v) // Masih bisa membaca 1, 2, 3 } fmt.Println("Channel sudah tertutup, loop berhenti.") }

Output yang dihasilkan:

Membaca: 1 Membaca: 2 Membaca: 3 Channel sudah tertutup, loop berhenti.

Mekanisme yang terjadi di sini:

  1. Channel diisi dengan 3 nilai.
  2. Channel ditutup.
  3. Loop for range tetap membaca semua nilai yang masih ada.
  4. Begitu semua data terbaca dan channel kosong, loop otomatis berhenti.

2. Bagaimana Ini Terjadi dalam Kode dengan Goroutine dan WaitGroup?

Dalam contoh sebelumnya dengan goroutine dan WaitGroup:

go func() { wg.Wait() // Tunggu semua worker selesai close(results) // Tutup channel setelah semua selesai }()

Mekanisme yang terjadi:

  1. Worker goroutine mengirimkan data ke channel results.
  2. Goroutine utama membaca data dari results dengan for range results.
  3. Ketika semua worker selesai (wg.Wait() selesai), goroutine terpisah menutup channel.
  4. Goroutine utama tetap bisa membaca semua data yang tersisa di dalam channel.
  5. Setelah channel benar-benar kosong dan ditutup, loop for range otomatis berhenti.

3. Apakah Bisa Terjadi Panic atau Error?

Ada satu hal yang menyebabkan panic pada channel: Mengirim data ke channel yang sudah ditutup!
Jika worker masih mencoba results <- data setelah channel ditutup, program akan panic.

Contoh yang menyebabkan panic:

package main import "fmt" func main() { ch := make(chan int, 3) close(ch) // Channel ditutup duluan ch <- 1 // Ini akan menyebabkan panic! }

Output error:

panic: send on closed channel

4. Kesimpulan dan Best Practice

Aman membaca dari channel yang sudah ditutup, asalkan masih ada data di dalamnya.
Gunakan for range untuk membaca channel, karena akan otomatis berhenti saat channel kosong dan tertutup.
Jangan pernah menulis ke channel yang sudah ditutup, karena ini akan menyebabkan panic.
💡 Sebaiknya hanya satu pihak yang bertanggung jawab menutup channel. Biasanya, goroutine yang membuat channel juga yang menutupnya.

Semoga ini membantu! Jika masih ada pertanyaan, silakan tanyakan lagi.