Golang Map 并发锁问题,解决方案

// 错误方案 不能直接使用指针
var syncLock *sync.RWMutex  
m := map[int]int{}  
i := 1  
for {  
    go func(val int) {
        syncLock.Lock()
        m[val] = val + 1
        syncLock.Unlock()
    }(i)
    i++
    time.Sleep(time.Nanosecond * 500)
}

以上代码,看似没有问题,执行的时候,会提示:无效的内存地址,是因为在使用的时候,只取了地址,但是地址并未初始化,所以会报nil

panic: runtime error: invalid memory address or nil pointer dereference  
[signal SIGSEGV: segmentation violation code=0x1 addr=0x10 pc=0x104e437]

goroutine 6 [running]:  
sync.(*RWMutex).RLock(0x0)  
    /usr/local/Cellar/go/1.10/libexec/src/sync/rwmutex.go:48 +0x27

正确解决方案  

// 正确方案 初始化不指向地址
var syncLock sync.RWMutex  
m := map[int]int{}  
i := 1  
for {  
    go func(val int) {
        syncLock.Lock()
        m[val] = val + 1
        syncLock.Unlock()
    }(i)
    i++
    time.Sleep(time.Nanosecond * 500)
}
// 正确方案 使用对象
var syncLock = new(sync.RWMutex)  
m := map[int]int{}  
i := 1  
for {  
    go func(val int) {
        syncLock.Lock()
        m[val] = val + 1
        syncLock.Unlock()
    }(i)
    i++
    time.Sleep(time.Nanosecond * 500)
}
// 正确方案 需要定义结构体,由结构体与MAP绑定,并继承锁的机制
a := struct {  
        sync.RWMutex
        m map[int]int
}{m: map[int]int{}}
i := 1  
for {  
    go func(val int) {
         // 写的时候使用写锁 如果是读取,请使用a.RLock() a.RUnlock()
        a.Lock()
        a.m[val] = val + 1
        a.Unlock()
    }(i)
    i++
    time.Sleep(time.Nanosecond * 500)
}

郝先生

继续阅读此作者的更多文章