golang的23种设计模式(一)—— 单例模式

单例模式

饿汉式

这种方式的单例对象在包加载的时候就会自动初始化instance实例,所以被称为饿汉式。

特点: 在包被导入的时候会自动初始化instance实例。

优点:

  • 实现简单。
  • 在程序启动时就已经创建好了单例对象,无需关心并发问题,线程安全。

缺点:

  • 如果单例对象占用资源较多,而在程序运行过程中其实并没有使用,就会造成资源的浪费。
  • 如果单例实例化时初始化内容过多,会造成程序加载用时较长。

注意: 尽管饿汉式实现单例模式的方式简单,但是大多数情况下不推荐,因为如果单例实例化时初始化内容过多,会造成程序加载用时较长。

package singleton

type Singleton struct{}

var instance = &Singleton{}

func GetInstance() *Singleton {
    return instance
}

懒汉式(Lazy Loading)

特点: 将实例化Singleton结构体的代码部分移到函数内部,这样将结构体实例化的步骤延迟到了GetInstance第一次被调用的时候。

优点:

  • 单例对象在需要的时候才创建,节约资源。

缺点:

  • 在多线程环境下不保证单例的唯一性,可能会创建多个单例对象。

注意: 这种方法通过instance==nil判断来实现单例并不是十分可靠,因为如果有多个goroutine调用GetInstance()就无法保证并发安全,可能会创建多个实例。

package singleton

type Singleton struct{}

var instance *Singleton

func GetInstance() *Singleton {
    if instance == nil {
        instance = &Singleton{}
    }
    return instance
}

懒汉式(Lazy Loading)–线程安全

特点: 支持并发,线程安全。

优点:

  • 单例对象在需要的时候才创建,节约资源。
  • 在多线程环境下,能保证单例的唯一性。

缺点:

  • 这种写法虽然线程安全,但是每次调用该方法时都需要进行锁操作,在性能上相对不高效。
package singleton

import "sync"

type Singleton struct{}

var instance *Singleton
var mu sync.Mutex

func GetInstance() *Singleton {
	mu.Lock()
    defer mu.Unlock()
    if instance == nil {
        instance = &Singleton{}
    }
    return instance
}

双重锁定

特点: 在懒汉式-线程安全的代码上加了一层判断,判断instance是否为nil,通过这种形式来兼顾安全和性能

优点:

  • 单例对象在需要的时候才创建,节约资源。
  • 在多线程环境下,能保证单例的唯一性。
  • 只有在第一次创建单例对象时才需要获取锁,提高了性能。

缺点:

  • 实现复杂。

解释:

  • 最外层的instance判断是为了提高程序的执行效率,避免每次调用GetInstance都去上锁,将加锁的粒度更加精细化,
  • 内层的instance判断则考虑了并发安全,即使在极端情况下多个goroutine走到加锁这一步,内层的判断也会生效
package singleton

import "sync"

type Singleton struct{}

var instance *Singleton
var mu sync.Mutex

func GetInstance() *Singleton {
    if instance == nil {
        mu.Lock()
        defer mu.Unlock()
        if instance == nil {
            instance = &Singleton{}
        }
    }
    return instance
}

Gopher 惯用方案

通过sync.Once 来确保创建对象的方法只执行一次,sync.Once内部本质上也是双重检查的方式,但在写法上会比自己写双重检查更简洁

优点:

  • 单例对象在需要的时候才创建,节约资源。
  • 在多线程环境下,能保证单例的唯一性。

缺点:

  • 相比于其他方法,没有明显的缺点
package singleton

import "sync"

type Singleton struct{}

var instance *Singleton
var once sync.Once

func GetInstance() *Singleton {
    once.Do(func () {
        instance = &Singleton{}
    })
    return instance
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值