golang学习———sync.Once(2)

本文介绍了Golang中sync.Once.Do()方法的实现原理及应用。通过对源码的解析,阐述了如何通过原子操作和互斥锁确保初始化操作只执行一次。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

在开发时,我们经常碰到这样的应用场景:只需要执行或初始化一次,例如,单例模式或是系统开启时的初始化。一般的语言通用做法是利用互斥操作设置标志变量,通过判断标志变量的值决定是否执行相关代码;golang语言的实现非常简单,只需一行代码,如下:

        import "sync"

var once sync.Once

func init() {

    //初始化代码

}


once.Do(init) // 只需一行代码,结构清晰,一目了然

那么once.Do()这个方法是如何实现的呢?我们来解析golang实现的一次操作:

    首先, “sync” 是一个引用的包,具体实现在该包中; Once是定义的一个结构体对象,如下:

     type Once struct {

           m Mutex

           done uint32

     }

     看到这里,我们基本应该可以猜出once.Do()的实现思路,Once.m是一个互斥锁,在进行Do()操作时,进行互斥操作;Once.done是一个标志变量,表示是否进行过Do()的操作。Do()的具体实现如下:

    func (o *Once) Do(f func()) {

        if atomic.LoadUint32(&o.done) == 1 {

return

        }

        o.m.Lock()

        defer o.m.Unlock()

        if o.done == 0 {

     defer automic.StoreUint32(&o.done, 1)

             f()

}

    }

    实现思路与我们的猜测基本一致,它引入了原子操作包  import "sync/atomic",通过automic.LoadUint32和automic.StoreUint32操作实现标志变量Once.done的载入和存储,这样更精细化的原子操作的实现能进一步提高系统处理的速度,减少协程对互斥锁不必要的等待。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值