Golang Concurrency #2
Mari kita mulai belajar concurrency di Golang dari dasar. Kita akan membahas dua konsep utama:
- Goroutine: Unit eksekusi ringan yang memungkinkan kita menjalankan fungsi secara konkuren (bersamaan).
- 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 fungsisayHellosecara konkuren.- Karena goroutine berjalan secara independen, fungsi
mainbisa selesai sebelumsayHellodieksekusi. - Kita menggunakan
time.Sleepuntuk memberikan waktu agar goroutine selesai. (Pada aplikasi nyata, kita bisa menggunakan mekanisme sinkronisasi sepertisync.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
workermengirim pesan ke channel denganmessages <- "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 dimainsampai semua goroutine selesai.
Kesimpulan
- Goroutine: Menjalankan fungsi secara konkuren dengan keyword
go. - Channel: Mengirim data antar goroutine dengan cara yang aman.
- 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!