一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第23天,点击查看活动详情。
sync Once
sync Once可以让代码只执行一次,即使是在高并发的情况下。
func main() {
doOnce()
}
func doOnce() {
var once sync.Once
onceBody := func() {
fmt.Println("Only once")
}
//用于等待协程执行完毕
done := make(chan bool)
for i := 0; i < 10; i++ {
go func() {
//把要执行的函数(方法)作为参数传给once.Do方法即可
once.Do(onceBody)
done <- true
}()
}
for i := 0; i < 10; i++ {
<-done
}
}
上面示例中启动10个协程执行once.Do(onceBody),但是结果显而易见,onceBody只执行了一次。
sync Once适用于创建某个对象的单位,或者只加载一次的资源这种只执行一次的场景。
sync.Cond
sync.Cond在go语言sync包提供的同步原语中使用的并不是很频繁,它用于发出信号(一对一)或广播信号(一对多)到goroutine,它具有阻塞协程和唤醒协程的功能。
sync.Cond有三个方法:
| 方法 | 解释 |
|---|---|
| Wait | 阻塞当前协程 |
| Signal | 唤醒一个等待时间最长的协程 |
| Broadcast | 唤醒所有等待的协程 |
sync.Map
sync.Map是并发版本的go语言的Map,sync.Map有一些方法:
| 方法 | 解释 |
|---|---|
| Store | 存储一对key-value值 |
| Load | 根据key获取对应的value值,可以判断key是否存在 |
| LoadOrStore | 如果key对应的value存在,则返回该value,如果不存在,存储value |
| Delete | 伤处一个key-value键值对 |
| Range | 循环迭代sync.Map,效果与for range一样 |
func main() {
m := &sync.Map{}
// 添加元素
m.Store(1, "one")
m.Store(2, "two")
// 获取元素1
value, contains := m.Load(1)
if contains {
fmt.Printf("%s\n", value.(string))
}
// 返回已存value,否则把指定的键值存储到map中
value, loaded := m.LoadOrStore(3, "three")
if !loaded {
fmt.Printf("%s\n", value.(string))
}
m.Delete(3)
// 迭代所有元素
m.Range(func(key, value interface{}) bool {
fmt.Printf("%d: %s\n", key.(int), value.(string))
return true
})
}