[设计模式 Go实现] 创建型~单例模式

使用懒惰模式的单例模式,使用双重检查加锁保证线程安全

代码实现

go 复制代码
package singleton

import "sync"

// Singleton 是单例模式接口,导出的
// 通过该接口可以避免 GetInstance 返回一个包私有类型的指针
type Singleton interface {
	foo()
}

// singleton 是单例模式类,包私有的
type singleton struct{}

func (s singleton) foo() {}

var (
	instance *singleton
	once     sync.Once
)

//GetInstance 用于获取单例模式对象
func GetInstance() Singleton {
	once.Do(func() {
		instance = &singleton{}
	})

	return instance
}

单元测试

go 复制代码
package singleton

import (
	"sync"
	"testing"
)

const parCount = 100

func TestSingleton(t *testing.T) {
	ins1 := GetInstance()
	ins2 := GetInstance()
	if ins1 != ins2 {
		t.Fatal("instance is not equal")
	}
}

func TestParallelSingleton(t *testing.T) {
	start := make(chan struct{})
	wg := sync.WaitGroup{}
	wg.Add(parCount)
	instances := [parCount]Singleton{}
	for i := 0; i < parCount; i++ {
		go func(index int) {
			//协程阻塞,等待channel被关闭才能继续运行
			<-start
			instances[index] = GetInstance()
			wg.Done()
		}(i)
	}
	//关闭channel,所有协程同时开始运行,实现并行(parallel)
	close(start)
	wg.Wait()
	for i := 1; i < parCount; i++ {
		if instances[i] != instances[i-1] {
			t.Fatal("instance is not equal")
		}
	}
}
相关推荐
witton3 小时前
Go语言网络游戏服务器模块化编程
服务器·开发语言·游戏·golang·origin·模块化·耦合
叹一曲当时只道是寻常3 小时前
Softhub软件下载站实战开发(十六):仪表盘前端设计与实现
前端·golang
Jerry Lau4 小时前
go go go 出发咯 - go web开发入门系列(一) helloworld
开发语言·前端·golang
天下一般4 小时前
go入门 - day1 - 环境搭建
开发语言·后端·golang
易元4 小时前
设计模式-模板方法模式
后端·设计模式
花好月圆春祺夏安5 小时前
基于odoo17的设计模式详解---策略模式
设计模式·策略模式
大P哥阿豪7 小时前
Go defer(二):从汇编的角度理解延迟调用的实现
开发语言·汇编·后端·golang
收破烂的小熊猫~17 小时前
《Java修仙传:从凡胎到码帝》第四章:设计模式破万法
java·开发语言·设计模式
佛祖让我来巡山20 小时前
【工厂和策略设计模式妙用】解决接口选择与多重if-else 问题
设计模式·策略模式·工厂模式
hqxstudying1 天前
Java创建型模式---原型模式
java·开发语言·设计模式·代码规范