Concurrency dalam Golang: Mengenal Goroutine dan Channel

Golang atau Go dikenal sebagai bahasa pemrograman yang sederhana, efisien, dan sangat mendukung pemrograman konkuren atau concurrent programming. Konsep concurrency memungkinkan program untuk melakukan banyak pekerjaan secara bersamaan, yang sangat penting dalam pengembangan aplikasi berskala besar dan performa tinggi. Artikel ini membahas dua fitur utama dalam concurrency di Go, yaitu goroutine dan channel.
Apa Itu Goroutine?
Goroutine adalah unit eksekusi ringan yang dijalankan bersamaan dengan goroutine lainnya dalam satu program. Goroutine dikelola oleh Go runtime, bukan oleh sistem operasi, sehingga jauh lebih ringan dibanding thread biasa.
Contoh penggunaan goroutine:
package main
import (
"fmt"
"time"
)
func sayHello() {
fmt.Println("Hello from Goroutine")
}
func main() {
go sayHello()
fmt.Println("Main function")
time.Sleep(1 * time.Second)
}
Mengenal Channel
Channel digunakan untuk berkomunikasi antar goroutine. Channel memungkinkan satu goroutine mengirim data ke goroutine lain dengan cara yang aman dan terstruktur.
Contoh penggunaan channel:
package main
import "fmt"
func sendMessage(ch chan string) {
ch <- "Hello from channel"
}
func main() {
ch := make(chan string)
go sendMessage(ch)
message := <-ch
fmt.Println(message)
}
Buffered dan Unbuffered Channel
Unbuffered channel adalah channel di mana proses kirim dan terima harus terjadi secara bersamaan. Sedangkan buffered channel memungkinkan menyimpan sejumlah data sebelum diterima.
ch := make(chan int, 2)
ch <- 1
ch <- 2
fmt.Println(<-ch)
fmt.Println(<-ch)
Select Statement
Select digunakan untuk menangani banyak channel secara bersamaan dalam satu blok kode.
select {
case msg1 := <-ch1:
fmt.Println("Received", msg1)
case msg2 := <-ch2:
fmt.Println("Received", msg2)
default:
fmt.Println("No message received")
}
Studi Kasus: Worker Pool
Salah satu implementasi umum concurrency adalah worker pool, yaitu sekelompok goroutine yang memproses pekerjaan dari channel.
func worker(id int, jobs <-chan int, results chan<- int) {
for j := range jobs {
fmt.Printf("Worker %d processing job %d\n", id, j)
results <- j * 2
}
}
Best Practice dan Masalah Umum
Best practice:
- Gunakan sync.WaitGroup untuk menunggu semua goroutine selesai bekerja.
- Gunakan channel sebagai media komunikasi antar goroutine, bukan berbagi memori langsung.
- Gunakan sync.Mutex jika perlu mengakses data bersama untuk menghindari race condition.
Masalah umum:
- Deadlock terjadi ketika semua goroutine menunggu dan tidak ada yang melanjutkan proses.
- Race condition terjadi ketika dua goroutine mengakses data yang sama secara bersamaan tanpa sinkronisasi.
- Memory leak dapat terjadi jika channel tidak ditutup setelah digunakan.
Concurrency di Go dirancang agar mudah digunakan namun tetap sangat kuat. Dengan memanfaatkan goroutine dan channel, kamu bisa membangun program yang efisien, cepat, dan dapat memanfaatkan banyak core CPU secara maksimal. Mulailah bereksperimen dan eksplorasi lebih lanjut untuk menguasai kekuatan concurrency dalam Go.