Go - 使用 sync.Map 來解決 map 的併發操作問題

前言

Golangmap 不是併發安全的,自 1.9 才引入了 sync.Mapsync.Map 的引入確實解決了 map 的併發安全問題,不過 sync.Map 卻沒有實現 len() 函數,如果想要計算 sync.Map 的長度,稍微有點麻煩,需要使用 Range 函數。

map 併發操作出現問題

func main() {
	demo := make(map[int]int)

	go func() {
		for j := 0; j < 1000; j++ {
			demo[j] = j
		}
	}()

	go func() {
		for j := 0; j < 1000; j++ {
			fmt.Println(demo[j])
		}
	}()

	time.Sleep(time.Second * 1)
}

執行輸出:

fatal error: concurrent map read and map write

sync.Map 解決併發操作問題

func main() {
	demo := sync.Map{}

	go func() {
		for j := 0; j < 1000; j++ {
			demo.Store(j, j)
		}
	}()

	go func() {
		for j := 0; j < 1000; j++ {
			fmt.Println(demo.Load(j))
		}
	}()

	time.Sleep(time.Second * 1)
}

執行輸出:

<nil> false
1 true

...

999 true

計算 map 長度

func main() {
	demo := make(map[int]int)

	for j := 0; j < 1000; j++ {
		demo[j] = j
	}

	fmt.Println("len of demo:", len(demo))
}

執行輸出:

len of demo: 1000

計算 sync.Map 長度

func main() {
	demo := sync.Map{}
	
	for j := 0; j < 1000; j++ {
		demo.Store(j, j)
	}

	lens := 0
	demo.Range(func(key, value interface{}) bool {
		lens++
		return true
	})

	fmt.Println("len of demo:", lens)
}

執行輸出:

len of demo: 1000

小結

  1. Load 加載 key 數據
  2. Store 更新或新增 key 數據
  3. Delete 刪除 key 數據
  4. Range 遍歷數據
  5. LoadOrStore 如果存在 key 數據則返回,反之則設置
  6. LoadAndDelete 如果存在 key 數據則刪除

以上,希望對你能夠有所幫助。

推薦閱讀

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章