如何理解Go里面的sync.Map

2023-04-14 00:18:00 sync map 理解

如何理解Go里面的sync.Map

Go里面的sync.Map是一个并发安全的Map,它可以在多个goroutine里面安全的读写。

为什么要使用sync.Map

在我们平时的开发中,我们经常会遇到需要用Map来存储数据的情况,比如说,我们可以用Map来存储用户的信息,每个用户的信息都可以通过用户的ID来进行查找。

如果我们只是在单个goroutine里面使用Map来存储数据,那么我们可以使用内置的Map来实现这个功能,但是如果我们要在多个goroutine里面同时读写Map里面的数据,就会有并发安全的问题了。

为了解决这个问题,我们可以使用sync.Map来代替内置的Map,sync.Map是并发安全的,在多个goroutine里面读写sync.Map是安全的。

使用sync.Map

使用sync.Map非常简单,我们只需要创建一个sync.Map的实例,然后就可以像使用内置的Map一样来使用它了。

比如说,我们可以这样来创建一个sync.Map的实例:

var m sync.Map

然后我们就可以像使用内置的Map一样来操作sync.Map了,比如说,我们可以使用store方法来存储数据,使用load方法来加载数据,使用delete方法来删除数据等等。

比如说,我们可以这样来存储一个用户的信息:

m.Store("1", User{ID: "1", Name: "张三"})

然后我们就可以通过用户的ID来加载用户的信息了:

var user User m.Load("1", &user)

如果我们要删除某个用户的信息,我们可以这样来做:

m.Delete("1")

需要注意的是,sync.Map是不能使用for range来进行遍历的,如果我们要遍历sync.Map里面的数据,我们可以使用Range方法来实现。

Range方法接收一个回调函数,我们可以在回调函数里面来遍历sync.Map里面的数据,比如说,我们可以这样来遍历sync.Map里面的数据:

m.Range(func(key, value interface{}) bool { // 遍历 sync.Map 里面的数据 fmt.Println(key, value) return true })

使用sync.Map的好处

使用sync.Map不仅可以解决并发安全的问题,而且还有一些其他的好处。

比如说,我们知道内置的Map在存储数据的时候,会为每个数据分配一个bucket来存储,如果我们存储的数据越多,那么bucket的数量也会越多,这样就会导致内存的浪费。

而sync.Map在存储数据的时候,是不会为每个数据分配一个bucket的,它会根据数据的数量来动态的分配bucket的数量,这样就可以避免内存的浪费。

此外,sync.Map还有一个特点就是,它不会在存储数据的时候进行拷贝,而内置的Map在存储数据的时候会进行拷贝,这样就可以减少内存的使用。

总结

sync.Map是一个并发安全的Map,它可以在多个goroutine里面安全的读写。使用sync.Map不仅可以解决并发安全的问题,而且还有一些其他的好处。

相关文章