在这个程序中,我们对map进行了并发的读和写,并且读和写的值并不一样,按照我们正常的逻辑来说,这个并发程序并没有问题,但是运行后却会发现出错了。 错误显示的是对map进行了并发的读和写。
为什么会出现这种问题呢?在map的扩容(具体的扩容过程自行百度)中,会产生新桶并且会逐步的删除旧桶,在并发的读写map时极易导致程序读到已删除的旧桶,go的创始人预见了这种情况,所以严格的限制了对map的并发读写。那么有没有办法解决这种情况呢?也有,最简单的办法就是在读写的时候加锁,但是这样在并发量大的情况下会严重影响运行速度。
这时就可以用到sync.map了。这边我们来看一下sync.map的源码,在sync包中的map.go中。
type Map struct { mu Mutex // read contains the portion of the map's contents that are safe for // concurrent access (with or without mu held). // // The read field itself is always safe to load, but must only be stored with // mu held.