併發環境應用map的解決方案

衆所周知,golang的map是非協程安全的(go1.6版本之後,go1.6以前讀安全),而併發讀寫map的需求應該是很廣泛的。舉例以下:golang

package main

import "fmt"

func main() {
    a := make(map[int]bool, 0)

    for i:=0;i<100;i++{
        go func() {
            for i := 0; i < 20000; i++ {
                a[i] = false
                fmt.Printf("%v %v\n",i,a[i])
            }

        }()
    }
}

運行報錯:
fatal error: concurrent map writes
1.9版本以前,官方提供的解決方案是本身封裝個帶同步鎖的struct。例如:安全

package main

import (
    "fmt"
    "sync"

)

type SafeMap struct{
    sync.RWMutex
    data map[int]int
}

func main() {
    a := SafeMap{data: make(map[int]int)}
    for i:=0;i<100;i++{
        go func() {
            for j := 0; j < 20000; j++ {
                a.Lock()
                a.data[j] = i
                fmt.Printf("%v %v\n", i, j)
                a.Unlock()
            }
        }()
    }
}

1.9版本之後,sync包引入了sync.Map,性能比起以前的解決方案有比較大的提高:併發

package main

    import (
        "fmt"
        "sync"
    )
    
    func main() {
        a := new(sync.Map)
        wg := new(sync.WaitGroup)
        wg.Add(100)
        for i:=0;i<100;i++{
            go func() {
                for j := 0; j < 100; j++ {
                    a.Store(i, j)
                }
                wg.Done()
            }()
        }
        wg.Wait()
        a.Range(func(key, value interface{}) bool {
            fmt.Printf("%v %v\n", key, value)
    
            return true
        })
    }
相關文章
相關標籤/搜索