最近在项目中需要在多线程下操作map,查阅资料后发现golang得sync包中有提供一个sync.map可以作为线程安全得map使用,但是最后同时推荐了另一个开源的cmap工具包,性能较sync.map更出色,所以没有使用golang的syanc包的map。在这里对两种map进行一下总结和学习。
1.sync.map
golang中如果在多个routine中使用map,是有可能会发生fatal错误导致程序挂掉的。所以在sync包中提供了一个线程安全的map,用Load和Store方法来代替对普通map的setget一般多routine中操作map都是加互斥锁,但枷锁在map操作频繁的时候性能会很差,而且写会阻塞读在sync.map中的思路是用空间换时间,先看下sync.map中主要的数据结构
mu是在阻塞操作时加的锁,read和dirty是两个map,可以把read理解为dirty的缓存(之后会详解sync.map中的读操作),且需要注意read和dirty中存储的value都是指针;misses是一个int值,用于记录在read中没有读到但在dirty中存在的值的次数(缓存未命中)且在misses值到一个阈值之后会发生一次dirty转换为read(后面简称dr转换);map中的value有两个特殊值expunged和nil,跟值的删除有关,之后再进行解释
首先看它的Load方法
Load方法比较简单,用于从map中获取对应key的value,主要逻辑是先从read中查找key,如果read中没有找到,再去dirty中找,并调