はじめに
go1.9で導入されたsyncmapを今更ながら試してみようと思います。
syncmap?
golangの様に簡単に並列処理を行える言語の場合には、共有リソースにアクセスする場合にはロックなどの処理が必要です。
これまでmapを共有リソースで使う場合は、sync.RWMutex等を使って同期していました。
syncmapでは、その辺の同期処理を実装する必要なくなるメリットがあります。
デメリットも公式に書いてあります。
サンプル
package syncmap_sample
import (
"fmt"
"sync"
)
type syncMap struct {
mapData *sync.Map
}
func NewMap() *syncMap {
return &syncMap{mapData: new(sync.Map)}
}
// StoreMap mapにデータをストアする
func (thisMap *syncMap) Store(key, value interface{}) {
thisMap.mapData.Store(key, value)
}
// LoadMap mapからデータを取得する
func (thisMap *syncMap) Load(key interface{}) (value interface{}, ok bool) {
return thisMap.mapData.Load(key)
}
// LoadOrStore mapにデータがあった場合は取得、ない場合はストアする。
func (thisMap *syncMap) LoadOrStore(key, value interface{}) (actual interface{}, loaded bool) {
return thisMap.mapData.LoadOrStore(key, value)
}
// Range 試しにkeyとvalueが同じものだけdumpしてみる
func (thisMap *syncMap) Range() {
thisMap.mapData.Range(func(key, value interface{}) bool {
if key == value {
fmt.Println("key:", key, " value:", value)
}
return true
})
}
// Delete mapにあるデータを削除
func (thisMap *syncMap) Delete(key interface{}) {
thisMap.mapData.Delete(key)
}
コードは、github.comに上げてあります。
個人的には、LoadOrStoreとRangeの使い道に悩みます。