[TOC] ## sync.Map - 并发安全的 map ``` errorMap := &sync.Map{} errorMap.Store(key, value) //更新或者新增 errorMap.Load(key) //取 errorMap.delete(key)//删 errorMap.Range(function(k,v interface{})bool{//todo }) //遍历 ``` ## sync.Mutex - 并发锁(互斥锁) 使用`Lock()`加锁后,便不能再次对其进行加锁,直到利用`Unlock()`解锁对其解锁后,才能再次加锁.适用于**读写不确定场景**,即读写次数没有明显的区别,并且只允许只有一个读或者写的场景,所以该锁叶叫做**全局锁** ``` lock := sync.Mutex{} lock.Lock() lock.Unlock() ``` ## sync.RWMutex 读写锁 Lock()   * 写锁,如果在添加写锁之前已经有其他的读锁和写锁,则lock就会阻塞直到该锁可用,为确保该锁最终 可用,已阻塞的 Lock 调用会从获得的锁中排除新的读取器,即写锁权限高于读锁,有写锁时优先进行写锁定 Unlock()  * 写锁解锁,如果没有进行写锁定,则就会引起一个运行时错误. RLock() * 读锁,当有写锁时,无法加载读锁,当只有读锁或者没有锁时,可以加载读锁,读锁可以加载多个,所以适用于"读多写少"的场景 RUnlock()  * 读锁解锁,RUnlock 撤销单次 RLock 调用,它对于其它同时存在的读取器则没有效果 ## sync.WaitGroup - 并发组 ``` var wg sync.WaitGroup // or wg := sync.WaitGroup{} wg.Add(10) for i := 0; i < 10; i++ { go func(i int) { log.Println("go ", i) wg.Done() }(i) } wg.Wait() log.Println("end") ``` ## sync.Pool - 对象池 `Pool`在多`goroutine`使用环境中是安全的。 `Pool`是用来缓存已经申请了的 目前未使用的 接下来可能会使用的 内存,以此缓解`GC`压力 ``` p := &sync.Pool{ //当对象池中没有东西时,返回此函数的值 New: func() interface{} { return 0 }, } a := p.Get().(int) p.Put(1) b := p.Get().(int) runtime.GC() //清楚对象池 c := p.Get().(int) fmt.Println(a, b, c) //0 1 0 ``` ## sync.Once - 只初始化一次即单例模式,(考虑并发) 如果没有初始化条件, ``` var myOnlyInstance = newMyType() ``` 有初始化条件 bad ``` public class MyType { static MyType single; public static MyType getSingle() { if (single == null) { single = new MyType(); } return single; } } ``` good ``` // The zero value for Once is ready to use var oSingle sync.Once var single *myType func getSingle() *myType { oSingle.Do(func(){ single = newMyType() }) return single } ```