sync.Once是详解Golang标准库中的一个同步工具,作用是同步保证指定函数只被执行一次,可以用于并发安全的工具单次初始化、单次执行等场景。详解
sync.Once的同步实现原理是基于原子性操作和锁的机制,只有一个方法Do(f func()),工具在第一次调用Do时,详解会执行函数f并将once对象标记为已完成;第二次及以后调用Do时,同步将不再执行函数f。工具看个例子:
package mainimport ( "fmt" "sync")func main() { var once sync.Once onceBody := func() { fmt.Println("只执行一次") } done := make(chan bool) for i := 0; i < 10; i++ { go func() { once.Do(onceBody) done <- true }() } for i := 0; i < 10; i++ { <-done }}
本例中开启了10个goroutine,详解每个goroutine中都调用了once.Do(onceBody),但onceBody方法只执行了一次。
sync.Once内部使用了一个bool类型的标志位,记录了对应函数是否已经被执行过。当Do方法第一次被调用时,该方法会获取锁并检查标志位,如果标志位为false,则执行函数并将标志位设置为 true,否则直接返回锁并退出。通过原子性的CAS操作进行设置和读取,保证并发的正确性。
假如想要实现一个对象的延迟初始化,只有在第一次被访问时才进行初始化操作,可以使用sync.Once来实现,代码如下:
type MyObject struct { // 懒加载初始化参数 initParams string // 初始化后的值 value string // once对象 once sync.Once}// 初始化函数,只被调用一次func (o *MyObject) init() { o.value = "initialized with " + o.initParams}// 获取对象的value字段,如果对象还没有初始化,则初始化之后再返回func (o *MyObject) Value() string { o.once.Do(o.init) return o.value}
使用了sync.Once实现了对象的懒加载,保证了并发访问的安全性和初始化只被执行一次。当第一个goroutine调用Value方法时,会执行init函数,初始化MyObject的value字段,并标记MyObject对象的once已经执行过。后续的其他goroutine再调用Value方法时,直接返回value字段,不再进行初始化。
责任编辑:姜华 来源: 今日头条 Sync.OnceGolang(责任编辑:百科)
深圳国际(00152.HK)遭UBS Group AG减持291.65万股 涉资约3681.5万港元
关于Chrome for Android 你必须知道的N件事儿
基石科技控股(08391.HK)完成配发6962.5万股 每股0.40港元