Golang map线程安全实现及sync.map使用及原理解析。
<h1>前言</h1>
众所周知,Golang 的map是不安全的,所以sync包提供了线程安全的map。接下来就是把我对sync.map的理解写出来分享给各位。
<h1>一、为什么map线程不安全?</h1>
map不是线程安全的。在同一时间段内,让不同 goroutine 中的代码,对同一个字典进行读写操作是不安全的。字典值本身可能会因这些操作而产生混乱,相关的程序也可能会因此发生不可预知的问题。
<h1>二、配合(锁)实现线程安全的map。</h1> <h2>1.悲观锁的形式</h2>悲观锁:进来的每一步操作都认为同时会有其他进程影响操作,所以提前加锁。
<pre><code class="lang-c hljs">lock<span class="token punctuation">.</span><span class="token function">Lock</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token comment">//map的增删改查操作</span> lock<span class="token punctuation">.</span><span class="token function">UnLock</span><span class="token punctuation">(</span><span class="token punctuation">)</span> </code></pre> <h2>2.乐观锁的形式</h2>乐观锁:因为map线程不安全是同时:读&&写||写&&写 造成的,所以在map写的时候加上锁就会提高map的性能。
<pre><code class="lang-c hljs"><span class="token comment">//查</span> lock<span class="token punctuation">.</span><span class="token function">Lock</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token comment">//map的增删改操作</span> lock<span class="token punctuation">.</span><span class="token function">UnLock</span><span class="token punctuation">(</span><span class="token punctuation">)</span> </code></pre> <h2>3.根据map实现原理,对小范围进行加锁。</h2>另一种设想是在buckets层面或者map更基本的组成层面加锁,根据乐观锁的情况进行小范围加锁。这里推荐一篇大佬的文章,写的非常好。(传送)
<h1>总结</h1>
map底层虽然写的尤为漂亮,但是为了效率,没有把线程安全安排上,所以另外加了sync.map,兼容线程安全。在我的理解中,sync.map实现就是依靠两张map对读操作和写操作分离,后续根据需要在把dirty map合入 read map中。相对于乐观锁实现的方式,写进程执行的时候,读进程也可能在read map上进行。
如有问题请联系本人指正,谢谢~
您可能感兴趣的文章:
Golang map线程安全实现及sync.map使用及原理解析。
通过实例深入理解sync.Map的工作原理
golang key map 所有_golang系列——高级语法之map
golang map 锁_Golang线程安全的map
golang map 锁_golang中线程安全的map
Golang map 并发读写问题源码分析
Golang线程安全Map:sync.Map使用小结
go二维map_Golang使用Map的正确姿势
golang key map 所有_谨慎使用golang中的map
Golang中sync.Map的实现原理