golang学习笔记——sync库


sync.WaitGroup 优雅的同步执行协程 package main   import (     "fmt"     "math/rand"     "sync"     "time" )   func f1(i int) {     defer wg.Done()     rand.Seed(time.Now().UnixNano())     time.Sleep(time.Millisecond * time.Duration(rand.Intn(3)))     fmt.Println(i) }   var wg sync.WaitGroup func main() {     for i := 0; i < 10; i++ {          wg.Add(1)          go f1(i)     }     wg.Wait() }   sync.Mutex 互斥锁 package main   import (     "fmt"     "sync" )   var x = 0 var wg sync.WaitGroup var mu sync.Mutex   func add() {     defer wg.Done()     for i := 0; i < 500000; i++ {          //公共资源加锁          mu.Lock()          x = x + 1          //解锁          mu.Unlock()     } }   func main() {     wg.Add(2)     go add()     go add()     wg.Wait()     fmt.Println(x) }   sync.RWMutex 读写锁
  • 基本遵循两大原则:1、获取到读锁之后可以随便读,多个goroutine同时读,但是任何goroutine都不能写;2、写的时候,啥也不能干。只能获取到写锁的那个goroutine可以写,其他的goroutine既不能读也不能写。
package main   import (     "fmt"     "sync"     "time" )   var (     x  int = 1     wg sync.WaitGroup     rw sync.RWMutex )   func write() {     defer wg.Done()     rw.Lock()     x = x + 1     rw.Unlock()     time.Sleep(time.Millisecond) }   func read() {     defer wg.Done()     rw.RLock()     fmt.Println(x)     rw.RUnlock() }   func main() {     for i := 1; i < 10; i++ {          wg.Add(1)          go write()     }     time.Sleep(time.Second)     for m := 0; m < 100; m++ {          wg.Add(1)          go read()     }     wg.Wait() }   sync.Once 保证只执行一次 package singleton   import (     "sync" )   type singleton struct {}   var instance *singleton var once sync.Once   func GetInstance() *singleton {     once.Do(func() {         instance = &singleton{}     })     return instance }   sync.Map 并发安全的map数据结构(Go中内置的map是并发不安全的) package main   import (     "fmt"     "strconv"     "sync" )   func main() {     var m = sync.Map{}     var wg sync.WaitGroup     for i := 0; i < 40; i++ {          wg.Add(1)          go func(i int) {                  defer wg.Done()                  str := strconv.Itoa(i)                  m.Store(i, str)                  v, _ := m.Load(i)                  fmt.Printf("key:%v,value:%v \n", i, v)          }(i)     }     wg.Wait() }