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()
}