go sync.once用法
baiyuxiong · · 12593 次点击 · · 开始浏览欢迎关注go语言微信公众号 每日go语言 golang_everyday
sync.once可以控制函数只能被调用一次。不能多次重复调用。示例代码:
package main
import (
"fmt"
"sync"
"time"
)
func main() {
o := &sync.Once{}
go do(o)
go do(o)
time.Sleep(time.Second * 2)
}
func do(o *sync.Once) {
fmt.Println("Start do")
o.Do(func() {
fmt.Println("Doing something...")
})
fmt.Println("Do end")
}
输出结果:
Start do
Doing something...
Do end
Start do
Do end
这里 Doing something 只被调用了一次。
查看go once的源码实现,也是非常的简单:
type Once struct {
m Mutex
done uint32
}
func (o *Once) Do(f func()) {
if atomic.LoadUint32(&o.done) == 1 {
return
}
// Slow-path.
o.m.Lock()
defer o.m.Unlock()
if o.done == 0 {
defer atomic.StoreUint32(&o.done, 1)
f()
}
}
核心思想是使用原子计数记录被执行的次数。使用Mutex Lock Unlock锁定被执行函数,防止被重复执行。
有疑问加站长微信联系(非本文作者)
入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889
关注微信- 请尽量让自己的回复能够对别人有帮助
- 支持 Markdown 格式, **粗体**、~~删除线~~、
`单行代码` - 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
- 图片支持拖拽、截图粘贴等方式上传
收入到我管理的专栏 新建专栏
欢迎关注go语言微信公众号 每日go语言 golang_everyday
sync.once可以控制函数只能被调用一次。不能多次重复调用。示例代码:
package main
import (
"fmt"
"sync"
"time"
)
func main() {
o := &sync.Once{}
go do(o)
go do(o)
time.Sleep(time.Second * 2)
}
func do(o *sync.Once) {
fmt.Println("Start do")
o.Do(func() {
fmt.Println("Doing something...")
})
fmt.Println("Do end")
}
输出结果:
Start do
Doing something...
Do end
Start do
Do end
这里 Doing something 只被调用了一次。
查看go once的源码实现,也是非常的简单:
type Once struct {
m Mutex
done uint32
}
func (o *Once) Do(f func()) {
if atomic.LoadUint32(&o.done) == 1 {
return
}
// Slow-path.
o.m.Lock()
defer o.m.Unlock()
if o.done == 0 {
defer atomic.StoreUint32(&o.done, 1)
f()
}
}
核心思想是使用原子计数记录被执行的次数。使用Mutex Lock Unlock锁定被执行函数,防止被重复执行。