Lompat ke konten Lompat ke sidebar Lompat ke footer

Golang Concurrency #2

 Mari kita mulai belajar concurrency di Golang dari dasar. Kita akan membahas dua konsep utama:

  1. Goroutine: Unit eksekusi ringan yang memungkinkan kita menjalankan fungsi secara konkuren (bersamaan).
  2. Channel: Sarana untuk berkomunikasi antar goroutine dengan aman.

1. Goroutine

Goroutine mirip dengan thread, namun lebih ringan dan mudah digunakan. Untuk menjalankan sebuah fungsi secara konkuren, cukup tambahkan keyword go sebelum pemanggilan fungsi.

Contoh Sederhana dengan Goroutine

package main import ( "fmt" "time" ) // Fungsi sederhana untuk mencetak pesan func sayHello() { fmt.Println("Hello, Goroutine!") } func main() { // Menjalankan sayHello secara konkuren sebagai goroutine go sayHello() // Memberikan waktu agar goroutine selesai dieksekusi time.Sleep(1 * time.Second) fmt.Println("Program selesai") }

Penjelasan:

  • go sayHello() memulai eksekusi fungsi sayHello secara konkuren.
  • Karena goroutine berjalan secara independen, fungsi main bisa selesai sebelum sayHello dieksekusi.
  • Kita menggunakan time.Sleep untuk memberikan waktu agar goroutine selesai. (Pada aplikasi nyata, kita bisa menggunakan mekanisme sinkronisasi seperti sync.WaitGroup.)

2. Channel

Channel digunakan untuk mengirim data antar goroutine dengan aman tanpa harus menggunakan mekanisme sinkronisasi manual seperti mutex. Channel dapat dibuat dengan tipe data tertentu.

Contoh Penggunaan Channel

package main import "fmt" func worker(messages chan string) { // Mengirim pesan ke channel messages <- "Pesan dari worker" } func main() { // Membuat channel dengan tipe string messages := make(chan string) // Menjalankan worker sebagai goroutine go worker(messages) // Menerima pesan dari channel msg := <-messages fmt.Println(msg) }

Penjelasan:

  • make(chan string) membuat channel untuk mengirim data bertipe string.
  • Fungsi worker mengirim pesan ke channel dengan messages <- "Pesan dari worker".
  • Di main, kita menunggu dan menerima pesan dari channel dengan <-messages.

3. Menggunakan sync.WaitGroup untuk Sinkronisasi

Menggunakan time.Sleep bukanlah cara terbaik untuk sinkronisasi. Kita dapat menggunakan sync.WaitGroup untuk memastikan semua goroutine selesai sebelum program berakhir.

Contoh dengan WaitGroup

package main import ( "fmt" "sync" ) func sayHello(wg *sync.WaitGroup, id int) { // Mengurangi counter WaitGroup saat goroutine selesai defer wg.Done() fmt.Printf("Hello dari goroutine %d\n", id) } func main() { // Membuat WaitGroup var wg sync.WaitGroup // Menjalankan beberapa goroutine for i := 1; i <= 3; i++ { // Menambah counter WaitGroup wg.Add(1) go sayHello(&wg, i) } // Menunggu semua goroutine selesai wg.Wait() fmt.Println("Semua goroutine selesai") }

Penjelasan:

  • wg.Add(1) menambah counter untuk setiap goroutine yang akan dijalankan.
  • defer wg.Done() di dalam goroutine memastikan counter dikurangi setelah goroutine selesai.
  • wg.Wait() akan memblokir eksekusi di main sampai semua goroutine selesai.

Kesimpulan

  1. Goroutine: Menjalankan fungsi secara konkuren dengan keyword go.
  2. Channel: Mengirim data antar goroutine dengan cara yang aman.
  3. sync.WaitGroup: Memastikan semua goroutine selesai sebelum program berakhir.

Cobalah untuk menulis dan menjalankan kode-kode di atas. Dengan memahami konsep dasar ini, kamu bisa mulai mengembangkan aplikasi konkuren yang lebih kompleks di Golang. Jika ada pertanyaan atau ingin contoh yang lebih mendalam, silakan tanya!