概念

单例模式:一个只允许创建一个实例的类叫做单例类,这种模式称为单例模式。

作用

类的实例具有全局唯一性,适用于一些场景,如管理配置的类,写log的类等,这种类只需要一个全局的实例来共享资源,无需创建多个实例,单例模式有利用节约资源、防止多个实例产生冲突。

相关知识点

  1. 在其他语言的讲解中,有一个通俗的说法,构建一个单例模式需要三要素:
    构造函数私有化
    静态实例的引用私有化
    返回静态实例的静态公有方法

  2. 实现方式有懒汉式和饿汉式之分。
    懒汉式:需要的时候才创建,在这种写法中,需要注意的是要注意并发调用创建函数的场景,需要用锁或其他并发控制原语来控制实例只会创建一次。
    饿汉式:事先创建好,需要时直接返回。

实现例子

  1. 单例模式两种实现方式
package singleton

import (
    "fmt"
    "sync"
)

var (
    lock     sync.Mutex
    instance *singleton
)

type singleton struct {
    Data int
    name string
}

func (s *singleton) String() string {
    return fmt.Sprintf("singleton data:%v, name:%v", s.Data, s.name)
}

// 懒汉式
func NewSingleton(data int, name string) *singleton {
    if instance == nil {
        lock.Lock()
                // 双重判断
        if instance == nil {
            instance = &singleton{
                Data: data,
                name: name,
            }
        }
        lock.Unlock()
    }
    return instance
}

// 饿汉式
var SingletonInstance *singleton = &singleton{2, "饿汉"}
  1. 使用sync标准库实现
sync库里面有Once类,可以控制某个逻辑只会执行一次,需要单例时直接使用该方式会很方便。

package singleton

import "sync"

var once sync.Once

func GetInstance() *singleton {
    once.Do(func() {
        instance = &singleton{}
    })
    return instance
}

转自:https://zhuanlan.zhihu.com/p/293959254