【Golang】设计模式 - Creational - Singleton

Posted by 西维蜀黍 on 2021-06-28, Last Modified on 2023-08-23

Singleton Pattern

Refer to https://swsmile.info/post/design-pattern-singleton-pattern/ for Singleton pattern.

Using init() functions

Package init() functions are guaranteed to be called only once and all called from a single thread ( they’re thread-safe unless you make them multi-threaded). But that makes you dependent on boot order. And you should not write codes in an *init ( )* that you need a guarantee of execution at any given time

type A struct {
	str string
}

var singleton *A

func init() {
	//initialize static instance on load
	singleton = &A{str: "abc"}
}

//GetInstanceA - get singleton instance pre-initialized
func GetInstanceA() *A {
	return singleton
}

Lazy Load

Using sync.Once

package singleton

import "sync"

type singleton struct {
}

var (
	instance *singleton
	once     sync.Once
)

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

Using sync.Mutex

package main

import (
    "fmt"
    "sync"
)

var lock = &sync.Mutex{}

type single struct {
}

var singleInstance *single

func getInstance() *single {
    if singleInstance == nil {
        lock.Lock()
        defer lock.Unlock()
        if singleInstance == nil {
            fmt.Println("Creating single instance now.")
            singleInstance = &single{}
        } else {
            fmt.Println("Single instance already created.")
        }
    } else {
        fmt.Println("Single instance already created.")
    }

    return singleInstance
}

Reference