Sync 同步包
sync 同步包提供7种并发工具类
1. Mutex 互斥锁
- sync.Mutex 互斥锁能够保证在同一时间只有一个goroutine持有锁,这就保证在某一段时间只有一个goroutine 能够访问共享资源,其他申请锁的goroutine将被阻塞,直到锁被释放,然后重新争抢锁的持有权。
//加锁
Lock()
//解锁
Unlock()
使用时可以用defer
来进行锁的释放,以避免忘记释放锁。
2. RWMutex 读写锁
RWMutex将读锁和写锁分开,为了保证在同一时间能有多个goroutine访问同一资源,需要满足以下条件:
- 在同一时间只有一个goutine能够获取到写锁。
- 在同一时间可以有任意多个goroutine获取到读锁。
- 在同一时间段只能存在读锁或者是写锁。
读写锁提供以下接口
func (rw *RWMutex) Lock() //写加锁
func (rw *RWMutex) Unlock() //写锁释放
func (rw *RWMutex) RLock() //读加锁
func (rw *RWMutex) RUnlock() //读锁释放
可以使用以上接口,来对goroutine进行读写分离的并发控制。
3. sync.WaitGroup 并发等待组
使用sync.WaitGroup的goroutine会等待预设好数量的goroutine都提交执行结束后,才会继续往下执行代码。
提供如下接口:
func (wg *WaitGroup) Add(delta int) //添加等待数量,传递复数表示任务减一
func (wg *WaitGroup) Done() //等待数量减一
func (wg *WaitGroup) Wait() //使goroutine等待于此
注意🍂:在goroutine调用WaitGroup.Wait()进行等待之前,需要保证waitGroup中等待数量不小于1,即waitGroup.Add()方法要在 wait()方法之前执行,否则等待就会被忽略。
同时,waitGroup.Done()执行次数要与waitGroup.Add()添加的等待数量一致
- 如果过少会导致程序的死锁
- 如果过多会导致程序panic
4. sync.Map 并发安全字典
Go语言原生的Map字典并不是并发安全的,在多个goroutine同时向Map中添加数据时,可能会导致部分数据的丢失,为了避免这种情况,Go1.9之后提供了sync.Map,相对于原生的Map,只提供如下接口:
func (m *Map) Load(key intrface{}) (value interface{},ok bool) //根据key 获取存储的值
func (m *Map) Store(key,value interface{}) //设置键值对
func (m *Map) LoadOrStore(key,value interface{}) (actual interface{},loaded bool) // 如果key存在,返回对应的value ,否则设置key-value对
func (m *Map) Delete(key interface{}) //删除一个key以及对应的键值对
func (m *Map) Range (f func(key, value innterface{}) bool) //无序遍历map
sync.Map对键值的类型没有限制,在一个sync.Map中可以同时存储多种不同类型的键值对。