Pengenalan sync.Map
sync.Map
ini sebenarnya mirip sekali dengan Generic Golangnya map
biasa, namun yang membedakan map
ini aman untuk digunakan saat concurrent goroutine.
sync.Map
adalah implementasi map yang memungkinkan kita bisa mengakses dengan aman dan memodifikasi datanya dari beberapa goroutine. Ini akan memberikan cara yang efisien untuk menyimpan dan mengambil nilai dengan kunci.
Selain itu, sync.Map
menggunakan kombinasi dari operasi atomic
, sync.RWMutex
dan struct
yang berbasi hash sehingga memastikan data tetap konsisten dan dapat diakses bahkan saat bersamaan beberapa goroutine memodifikasi map tersebut.
Kenapa kita harus menggunakan sync.Map
?
sync.Map
cocok digunakan untuk kita yang sering menggunakan concurrence yang tinggi diaman banyak goroutine yang mengakses dan memodifikasi data secara bersama-sama.
Penting untuk dicatat bahwa sync.Map
tidak bisa menjamin data tersebut berurutan ketika dikeluarkan datanya dan juga key
tidak dapat diproses dalam urutan tertentu. Selain itu, tidak seperti pada golang biasa, sync.Map
tidak mendukung beberapa operasi golang seperti delete
, range
. Maka, perlu kita hati-hati juga dalam penggunaan tipe seperti ini.
Penggunaan Method
Beberapa method yang tersedia pada sync.Map
adalah sebagai berikut:
Load(key interface{}) (value interface{}, ok bool)
digunakan untuk mengambil data dari map yang sudah diinisialisasiStore(key, value interface{})
digunakan untuk menyimpan data ke dalam map dengan key tertentu.Delete(key interface{})
digunakan untuk menghapus data yang dengankey
tertentu pada suatu map.Range(f func(key, value interface{}) bool)
digunakan untuk mengeluarkan data dengan kondisi apakah ada atau tidak data dengankey
yang akan kita cari.LoadOrStore(key, value inteface{})(actual interface{}, loaded bool)
digunakan untuk mengambil suatu data darimap
tetapi jika tidak ada akan otomatis menyimpannya ke dalam map tersebut lalu mengeluarkan map yang aktualnya.
Implementasi dan sampel sync.Map
Kita coba lihat kode implementasi dibawah ini.
func main() {
var data sync.Map
var AddToMap = func(value int) {
data.Store(value, value)
}
for i := 0; i < 100; i++ {
go AddToMap(i)
}
time.Sleep(5 * time.Second)
data.Range(func(key, value interface{}) bool {
fmt.Println(key, ":", value)
return true
})
}
Maka, hasil kode diatas jika kita jalankan akan seperti dibawah ini
21 : 21
63 : 63
...
...
9 : 9
19 : 1
Kita bisa lihat bahwa data yang dikeluarkan tidak berurutan karena sebenarnya semua data yang disimpan pada map
tersebut tidak beraturan karena disimpan menggunakan goroutine.
Kesimpulan
sync.Map
adalah struct kompleks yang umumnya digunakan untuk membaca dan satu lagi untuk menyimpan element yang baru. sync.Map
ini didalamnya memiliki pendekatan map + sync.RWMutex
pada metriknya, tetapi juga bisa menjadi yang terbaik dari sisi membaca data. Ketika ada sinkronisasi data dari membaca dan memperbarui maka sync.Map
ini yang paling unggul.