golang 的版本是 1.9.2
最近接触 golang 的并发加锁功能,按照例子做了一个多 goroutine 计数的练习,发现加锁和不加锁的运行结果是一样的,请问这是机器的缘故吗?(至少在我的电脑上和 https://play.golang.org/ 上模拟是这样的) 还是说 1.9 版本的 go 已经不用 mutex 锁数据了?如果是我的测试方法的问题,那么如何能正确的方式测试出加锁和不加锁的区别呢?
代码如下:
package main
import (
"fmt"
"sync"
"time"
)
type SafeCounter struct {
v map[string]int
mux sync.Mutex
}
func (c *SafeCounter) Inc(key string) {
c.mux.Lock()
c.v[key]++
c.mux.Unlock()
}
func (c *SafeCounter) Value(key string) int {
defer c.mux.Unlock()
c.mux.Lock()
return c.v[key]
}
func main() {
c := SafeCounter{
v: make(map[string]int),
}
for i := 0; i < 1000; i++ {
go c.Inc("somekey")
}
time.Sleep(time.Second)
fmt.Println(c.Value("somekey"))
}
输出结果是 1000
把所有的锁去掉,还是 1000
map
是非线程安全的。从go1.6开始,runtime会对并发读写map进行检测,一旦检测到有并发读写map的情况,会引发crash。sync.Map
是线程安全的。