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 數據則刪除

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

推薦閱讀


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM