go语言:给map上锁

map不是goroutine safe的,在多goroutine并发时需要上锁。

不上锁会出现什么问题呢?

资源竞争:会出现脏读,丢失更新等一系列状况。如读到的是旧数据或是读出来的对象已经被删除了,引发panic。

锁用的不对会发生什么呢?

  • 第一种情况:死锁(dead lock),卡住。使用时lock了,但没有unlock,就锁死了。另外,注册copy对象里带锁时,注意是不是带锁状态一起拷贝了,这个也会死锁。
  • 第二种情况:低效。锁对象时进行了耗时操作,导致了长时间的等待。代码要尽量减少锁持有的时间。

怎样才是上锁正确的姿势呢?

总结如下:(按效率从高到低排序)

  1. 无锁:无招胜有招。避免使用锁是最高效的。在不会引发资源竞争的地方就不要用锁。或者通过设计,将业务放在同一个goroutine下执行。
  2. concurrent-map
    分段锁: 其中对key进行分段,一个段内使用一个锁,这样操作不同的key时,避免锁的阻塞开销,提高了效率。但是增加了内存消耗。
  3. sync.Map
    官方实现,内部使用了读写两张表。在读出写少效率比较高,但写多时推荐使用分段锁。
  4. 给map加读写锁
    在轻量级,使用不是很频繁时使用。

没有一种锁适合所有场合下使用,实际的使用按需求的不同。

发布了19 篇原创文章 · 获赞 2 · 访问量 678

猜你喜欢

转载自blog.csdn.net/weixin_43465618/article/details/104589931