文章目录
单例分为, 执行时机分为: 饿汉, 懒汉两种
- 饿汉: 进程启动时执行, 优点是更容易暴露问题, 缺点是进程启动时会执行太多耗时操作
- 懒汉: 使用时执行, 优点是把耗时操作分散到进程使用的过程中, 缺点是问题会被延迟暴露, 不易于定位问题
在 go 中可以通过 sync.Once 实现
package singleton
import "sync"
// 变量实例
var (
once sync.Once
cli *client
)
// 类型, 构造函数
type client struct{}
func newClient() *client {
return &client{}
}
// InitClient
// 1. 可在 package 的 init() 函数中, 被自动调用, 是饿汉
// 2. 也可在进程初始化时, 被手动调用, 是饿汉
// 3. 在使用时才调用, 是懒汉
func InitClient() *client {
once.Do(func() {
cli = newClient()
})
return cli
}
单测:
package singleton
import (
"github.com/stretchr/testify/require"
"testing"
)
func TestInitClient(t *testing.T) {
cli1 := InitClient()
cli2 := InitClient()
require.Equalf(t, cli1, cli2, "单例, 构造的指针应相同")
}
func BenchmarkInitClient(b *testing.B) {
b.RunParallel(func(pb *testing.PB) {
for pb.Next() {
cli1 := InitClient()
cli2 := InitClient()
require.Equalf(b, cli1, cli2, "单例, 构造的指针应相同")
}
})
}
执行:
go test .
go test -bench .