sync.Once
sync.Once是Golang标准库中的一个同步工具,作用是保证指定函数只被执行一次,可以用于并发安全的单次初始化、单次执行等场景。
使用方法和示例
sync.Once的实现原理是基于原子性操作和锁的机制,只有一个方法Do(f func()),在第一次调用Do时,会执行函数f并将once对象标记为已完成;第二次及以后调用Do时,将不再执行函数f。看个例子:
本例中开启了10个goroutine,每个goroutine中都调用了once.Do(onceBody),但onceBody方法只执行了一次。
sync.Once内部使用了一个bool类型的标志位,记录了对应函数是否已经被执行过。当Do方法第一次被调用时,该方法会获取锁并检查标志位,如果标志位为false,则执行函数并将标志位设置为 true,否则直接返回锁并退出。通过原子性的CAS操作进行设置和读取,保证并发的正确性。
假如想要实现一个对象的延迟初始化,只有在第一次被访问时才进行初始化操作,可以使用sync.Once来实现,代码如下:
使用了sync.Once实现了对象的懒加载,保证了并发访问的安全性和初始化只被执行一次。当第一个goroutine调用Value方法时,会执行init函数,初始化MyObject的value字段,并标记MyObject对象的once已经执行过。后续的其他goroutine再调用Value方法时,直接返回value字段,不再进行初始化。