序
代码实现
单例模式采用了 饿汉式 和 懒汉式 两种实现,个人其实更倾向于饿汉式的实现,简单,并且可以将问题及早暴露,懒汉式虽然支持延迟加载,但是这只是把冷启动时间放到了第一次使用的时候,并没有本质上解决问题,并且为了实现懒汉式还不可避免的需要加锁。
饿汉式
代码实现:
1 2 3 4 5 6 7 8 9 10 11 12 13
| package singleton
type Singleton struct{}
var singleton *Singletonfunc init() { singleton = &Singleton{} }
func GetInstance() *Singleton { return singleton }
|
单元测试:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| package singleton_test import ( "testing" singleton "github.com/stretchr/testify/assert" )
func TestGetInstance(t *testing.T) { assert.Equal(t, singleton.GetInstance(), singleton.GetInstance()) }
func BenchmarkGetInstanceParallel(b *testing.B) { b.RunParallel(func(pb *testing.PB) { for pb.Next() { if singleton.GetInstance() != singleton.GetInstance() { b.Errorf("test fail") } } }) }
|
懒汉式(双重检测)
代码实现:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| package singleton import "sync"
var ( lazySingleton *Singleton once = &sync.Once{})
func GetLazyInstance() *Singleton { if lazySingleton == nil { once.Do(func() { lazySingleton = &Singleton{} }) } return lazySingleton }
|
单元测试:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| package singleton_test import ( "testing" singleton "github.com/stretchr/testify/assert" )
func TestGetInstance(t *testing.T) { assert.Equal(t, singleton.GetInstance(), singleton.GetInstance()) }
func BenchmarkGetInstanceParallel(b *testing.B) { b.RunParallel(func(pb *testing.PB) { for pb.Next() { if singleton.GetInstance() != singleton.GetInstance() { b.Errorf("test fail") } } }) }
|