单例模式

单例模式,算是最常见的设计模式了吧,他很简单,就是确保一个类只有一个实例。常用于保存一些全局状态信息。

下面是来自wikipedia的描述:

单例模式,也叫单子模式,是一种常用的软件设计模式,属于创建型模式的一种。在应用这个模式时,单例对象的类必须保证只有一个实例存在。许多时候整个系统只需要拥有一个的全局对象,这样有利于我们协调系统整体的行为。比如在某个服务器程序中,该服务器的配置信息存放在一个文件中,这些配置数据由一个单例对象统一读取,然后服务进程中的其他对象再通过这个单例对象获取这些配置信息。这种方式简化了在复杂环境下的配置管理。

Golang实现

懒汉模式

所谓懒汉模式,就是指对象在需要的时候才进行创建,为什么叫懒汉模式,因为他很懒,所以他不会在不使用这个对象的时候进行创建,而是等到要使用的时候才去创建对象

不加锁实现

package singleton

type Singleton struct{}

var lazySingleton *Singleton

func GetInstance() *Singleton {
    if lazySingleton == nil {
        lazySingleton = new(Singleton)
    }
    return lazySingleton
}

对于不加锁实现,可能存在线程安全问题,在高并发的情况下,多个线程同时调用 GetInstance()方法,都会检测到 lazySingletonnil,因此会创建多个对象。

加锁实现(双重检测)

使用Lock和Unlock,通过加锁操作,在检测到 lazySingletonnil时,加锁,同时再次检测,若为空,则创建对象,这样就解决了线程安全问题

package singleton

import "sync"

type Singleton struct{}

var lazySingleton *Singleton
var lock sync.Mutex

func GetInstance() *Singleton {
    if lazySingleton == nil {
        lock.Lock()
        if lazySingleton == nil {
            lazySingleton = new(Singleton)
        }
        lock.Unlock()
    }
    return lazySingleton
}

在Golang中,这种操作有着更加优雅的实现,即使用 once.Do()

package singleton

import "sync"

type Singleton struct{}

var lazySingleton *Singleton
var once = &sync.Once{}

func GetInstance() *Singleton {
    if lazySingleton == nil {
        once.Do(func() {
            lazySingleton = new(Singleton)
        })
    }
    return lazySingleton
}

饿汉模式

所谓饿汉模式,指的是在一开始就创建实例,而非等到使用时才创建,为何要叫饿汉模式,因为他饿,所以着急吃饭,所以就不能等到要用了才创建,必须在用之前就要创建实例。

饿汉模式的实现比较简单,只需要在 init()函数里面创建实例即可

package singleton

type Singleton struct{}

var hungrySingleton *Singleton

func init() {
    hungrySingleton = new(Singleton)
}

func GetInstance() *Singleton {
    return hungrySingleton
}
最后修改:2021 年 12 月 28 日
如果觉得我的文章对你有用,请随意赞赏