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()
}
 
 
posted @ 2021-03-05 21:24  GPHPER  阅读(152)  评论(0编辑  收藏  举报
TOP