GO语言设计模式-单例模式
2022-05-22 18:01:13    84    0    0
weibo-007

GO语言设计模式-单例模式

什么是单例模式

单例模式是一种常用的软件设计模式,其定义是单例对象的类只能允许一个实例存在。

许多时候整个系统只需要拥有一个的全局对象,这样有利于我们协调系统整体的行为。比如在数据库连接中,我们只希望进程内所有的访问DB都是通过一个数据库连接进行的。

普通实现-并发不work

单例模式第一种实现方式

// 单例模式
package design

import "fmt"

type singleton struct {
	Name string
}

var instance *singleton

func GetInstance() *singleton {
	if instance == nil {
		fmt.Println("init") //这里每实例化一次,输出init
		instance = &singleton{}
	}
	return instance
}

这种实现方式在没有并发的情况下是正常工作的

package main

import (
	"learn/design"
)

func main() {
	//串行执行正常
	design.GetInstance() //输出init
	design.GetInstance() //不输出init
}

但是一旦出现并发的情况,这种实现方式是就不能正常工作了

package main

import (
	"learn/design"
	"sync"
)

func main() {
	//并发不正常
	var wg sync.WaitGroup
	for i := 0; i < 10; i++ {
		wg.Add(1)
		go func() {
			defer wg.Done()
			design.GetInstance() //每一次,均输出init
		}()
	}
	wg.Wait()
}

once 方式实现-并发work

上面实现的第一种方式在并发情况下并不能正常work,这里使用once方式支持并发执行一次,一般比较常用的就是这种方式了

// 单例模式
package design

import (
	"fmt"
	"sync"
)

type singleton struct {
	Name string
}

var instance *singleton
var once sync.Once

func GetInstance() *singleton {
	if instance == nil {
		once.Do(func() {
			fmt.Println("init") //这里每实例化一次,输出init
			instance = &singleton{}
		})
	}
	return instance
}

sync.Mutex锁方式实现-并发work

除了上面的使用once方式实现,还可以使用锁实现并发下只实例化一次

// 单例模式
package design

import (
	"fmt"
	"sync"
)

type singleton struct {
	Name string
}

var instance *singleton
var mu sync.Mutex
var isSuccess = 0

func GetInstance() *singleton {
	if isSuccess == 1 {
		return instance
	}
	mu.Lock()
	defer mu.Unlock()
	if isSuccess == 0 {
		fmt.Println("init") //这里每实例化一次,输出init
		instance = &singleton{}
		isSuccess = 1
	}
	return instance
}

 

 

 

Pre: GO语言设计模式-工厂模式

Next: 关于URL编码常见的三个错误

84
Sign in to leave a comment.
No Leanote account? Sign up now.
0 comments
Table of content