Go学习笔记—锁(sync包)

并发安全和锁
1. sync.Mutex—实现互斥锁
var lock sync.Mutex
var x int
func add() { //这样,在多个goroutine同时访问x时,才不会造成x错误
	for i := 0; i < 5000; i++ {
		lock.Lock() // 加锁
		x = x + 1
		lock.Unlock() // 解锁
	}
}
2. sync.RWMutex—实现读写互斥锁

​ 读写锁分为两种:读锁和写锁。当一个goroutine获取读锁之后,其他的goroutine如果是获取读锁会继续获得锁,如果是获取写锁就会等待;当一个goroutine获取写锁之后,其他的goroutine无论是获取读锁还是写锁都会等待。

var rwlock sync.RWMutex
rwlock.Lock()        // 加写锁
rwlock.Unlock()       // 解写锁
rwlock.RLock()        //  加读锁
rwlock.RUnlock()      // 解读锁
3. sync.WaitGroup—实现并发任务的同步

​ sync.WaitGroup返回一个非引用类型对象(维护一个计数器,计数器为0时,Wait()才会让函数继续向下运行)

func f(i int, wg *sync.WaitGroup) {
	fmt.Println(i)
	wg.Done() //Done每次将计数器-1
}

func main() {
	wg := sync.WaitGroup{}
	wg.Add(100) //计数器初值设置为100
	for i := 0; i < 100; i++ {
		go f(i, &wg) //开启一个并行线程
	}
	wg.Wait() //计数器为0时才会继续运行后续程序,否则拦截
}
4. sync.Once—实现唯一初始化
var once sync.Once
once.Do(初始化函数)//do实际上就是互斥锁+布尔变量,保证这个方法只会被安全的执行一次

//例如下面我们使用Once实现单例模式:
type singleton struct {}

var instance *singleton
var once sync.Once

func GetInstance() *singleton {
    once.Do(func() {
      instance = &singleton{}
    })
    return instance
}
5. sync.Map—实现并发安全的Map
操作 作用
var m = sync.Map{} 初始化
m.Store(key, n) 存入键值对
value, _ := m.Load(key) 取出键值对
Delete(key) 删除键值对
6. sync/atomic—实现原子操作
函数 作用
func AddInt32(addr *int32, delta int32) (new int32) 加操作
func CompareAndSwapInt32(addr *int32, old, new int32) (swapped bool) 比较old==new,为否则将new存入addr
func SwapInt32(addr *int32, new int32) (old int32) 直接将new存入addr
func LoadInt32(addr *int32) (val int32) 读取addr下的变量值
func StoreInt32(addr *int32, val int32) 将val存入addr下

你可能感兴趣的:(Golang,go,并发)