package main
import (
"fmt"
"sync"
"time"
)
func main() {
rw := sync.RWMutex{}
//可以让多个协程同时读取某对象
//初始值为解锁状态,通常作为其他结构体的匿名字段使用
//可以安全的在多个协程中并行使用
rw.Lock() // 设置为写状态,禁止其他协程读取或写入
rw.Unlock() // 解锁状态,如果未被锁定---> panic
rw.RLock() // 设置为写状态,禁止其他协程写入;但是可以读取
rw.RUnlock() // 解锁状态,如果未被锁定---> panic
rw.RLocker() // 返回一个互斥锁,将rw.Rlock和rw.RUnlock封装过程一个Locker接口
wg := sync.WaitGroup{}
wg.Add(1) // 计数器加1,必须是正数
wg.Done() // 计数器减1,直到归零,如果小于0,则该操作会引发panic
wg.Wait()
//条件等待,直到信号发送过来
cond := sync.NewCond(new(sync.Mutex)) // 用一把锁
for i := 0; i < 2; i++ {
go func() {
cond.L.Lock()
cond.Wait() // 等待发送信号,消费一个信号
fmt.Printf("%p\t%v\n", cond.L, cond.L)
//time.Sleep(time.Second)
cond.L.Unlock() // 多次wait 如果不释放锁,别的抢不到。
}()
}
time.Sleep(time.Second) // 在发信号之前,要有等待的cond
cond.Signal() // 只唤醒 1个 等待c的goroutine
cond.Signal() // 只唤醒 1个 等待c的goroutine
time.Sleep(time.Second * 2)
on := sync.Once{}
for i := 0; i < 2; i++ {
go func() {
fmt.Println("====")
on.Do(func() {
fmt.Println("-------")
})
}()
}
time.Sleep(time.Second)
var syncMap sync.Map
//并发操作一个map的时候,内置的map不是并发安全啊
syncMap.Store("key1", "value1")
fmt.Println(syncMap.Load("key"))
syncMap.LoadOrStore("key2", "value2")
syncMap.Delete("key")
syncMap.Range(func(key, value interface{}) bool {
fmt.Println(key, value)
return true // 是否继续进行遍历
})
}