代码实现

单例模式采用了 饿汉式 和 懒汉式 两种实现,个人其实更倾向于饿汉式的实现,简单,并且可以将问题及早暴露,懒汉式虽然支持延迟加载,但是这只是把冷启动时间放到了第一次使用的时候,并没有本质上解决问题,并且为了实现懒汉式还不可避免的需要加锁。

饿汉式

代码实现:

1
2
3
4
5
6
7
8
9
10
11
12
13
package singleton

// Singleton 饿汉式单例
type Singleton struct{}

var singleton *Singletonfunc init() {
singleton = &Singleton{}
}

// GetInstance 获取实例
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{})

// GetLazyInstance 懒汉式
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")
}
}
})
}