前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Golang单例模式

Golang单例模式

作者头像
李海彬
发布2018-03-28 11:23:55
7040
发布2018-03-28 11:23:55
举报
文章被收录于专栏:Golang语言社区Golang语言社区

单例模式,是一种常用的软件设计模式,在它的核心结构中只包含一个被称为单例的特殊类。通过单例模式可以保证系统中一个类只有一个实例且该实例易于外界访问,从而方便对实例个数的控制并节约系统资源。

懒汉模式(Lazy Loading)

懒汉模式是开源项目中使用最多的一种,最大的缺点是非线程安全的

代码语言:javascript
复制
type singleton struct {
}

// private
var instance *singleton

// public
func GetInstance() *singleton {
    if instance == nil {
        instance = &singleton{}     // not thread safe
    }
    return instance
}

带锁的单例模式

代码语言:javascript
复制
type singleton struct {
}

var instance *singleton
var mu sync.Mutex

func GetInstance() *singleton {
    mu.Lock()
    defer mu.Unlock()

    if instance == nil {
        instance = &singleton{}     // unnecessary locking if instance already created
    }
    return instance
}

这里使用了Go的sync.Mutex,其工作模型类似于Linux内核的futex对象,具体实现极其简单,性能也有保证初始化时填入的0值将mutex设定在未锁定状态,同时保证时间开销最小这一特性允许将mutex作为其它对象的子对象使用

带检查锁的单例模式

代码语言:javascript
复制
    if instance == nil {     // <-- Not yet perfect. since it's not fully atomic
        mu.Lock()
        defer mu.Unlock()
 
        if instance == nil {
            instance = &singleton{}
        }
    }
    return instance
}

这是一个不错的方法,但是还并不是很完美。因为编译器优化没有检查实例存储状态。如果使用sync/atomic包的话 就可以自动帮我们加载和设置标记。

代码语言:javascript
复制
import "sync"
import "sync/atomic"

var initialized uint32
...

func GetInstance() *singleton {

    if atomic.LoadUInt32(&initialized) == 1 {
        return instance
    }

    mu.Lock()
    defer mu.Unlock()

    if initialized == 0 {
         instance = &singleton{}
         atomic.StoreUint32(&initialized, 1)
    }

    return instance
}

比较好的一种方式sync.Once

代码语言:javascript
复制
import (
    "sync"
)
 
type singleton struct {
}
 
var instance *singleton
var once sync.Once
 
func GetInstance() *singleton {
    once.Do(func() {
        instance = &singleton{}
    })
    return instance
}

引文:

https://xiequan.info/go%E7%9A%84%E5%8D%95%E4%BE%8B%E6%A8%A1%E5%BC%8F/

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2017-11-13,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 Golang语言社区 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档