美文网首页
go单例模式之懒汉模式

go单例模式之懒汉模式

作者: CaiGuangyin | 来源:发表于2020-01-05 14:49 被阅读0次

    可以通过sync包中的sync.Once实现单例模式。

    var once sync.Once
    // 传入方法Do()中的函数只会被执行一次。
    once.Do(func(){})
    

    如下是once.go中的Do()方法的源码:

    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()
        }
    }
    

    下面是用sync.Once实现的单例模式

    package main
    
    import (
        `fmt`
        `sync`
    )
    
    type Singleton struct {}
    
    var singleton *Singleton
    var once sync.Once
    
    func GetSingletonObj() *Singleton {
        once.Do(func() {
            fmt.Println("create singletonObj.")
            singleton = new(Singleton)
        })
        return singleton
    }
    
    func main() {
        var wg sync.WaitGroup
        for i:=0;i<10;i++ {
            wg.Add(1)    // 往等待组中添加一个协程
            go func() {
                singleObj := GetSingletonObj()
                            // 打印singleObj的指针
                fmt.Printf("singleObj mem addr: %p\n", singleObj)
                wg.Done()    // 协程执行完毕,会调用`wg.Add(-1)`将计数减1
            }()
        }
        wg.Wait()    // 等待所有协程执行完毕
    }
    

    sync.WaitGroup的作用是让主函数main()等待所有协程go func(){}执行完后才退出。

    输出的结果如下:

    create singletonObj.
    singleObj mem addr: 0x5851d0
    singleObj mem addr: 0x5851d0
    singleObj mem addr: 0x5851d0
    singleObj mem addr: 0x5851d0
    singleObj mem addr: 0x5851d0
    singleObj mem addr: 0x5851d0
    singleObj mem addr: 0x5851d0
    singleObj mem addr: 0x5851d0
    singleObj mem addr: 0x5851d0
    singleObj mem addr: 0x5851d0
    

    从输出结果可以看出,create singletonObj只被打印了一次,也就证明传入once.Do()中的函数只被执行了一次,而GetSingletonObj()只在第一次执行时会创建一个singleton,后面每次执行返回的都是同一个singleton,从输出结果的singleObj mem addr就可以看出来。

    相关文章

      网友评论

          本文标题:go单例模式之懒汉模式

          本文链接:https://www.haomeiwen.com/subject/rnoqactx.html