起因
今天看到项目中的kafka客户端包装结构体的获取是单例模式<br>单例的实现是老生常谈的问题了,懒汉饿汉线程安全,因为看到项目中写的还是有些问题,网上go单例实现的搜索结果比较少经测试也并不靠谱,所以在这记录下
现状
当前有的项目直接使用Mutex锁,有的就直接判断nil则创建,对于前者,每次都加锁性能差,对于后者则会出现多个实例,也就不是单例了
改进
进而想要改进一下,在这不讨论饿汉和线程非安全的实现,对于go中线程安全的懒汉实现,常见两种:
- 双重检验
- sync.Once
双重检验示例:
package main
import (
"sync"
"testing"
)
var (
instance *int
lock sync.Mutex
)
func getInstance() *int {
if instance == nil {
lock.Lock()
defer lock.Unlock()
if instance == nil {
i := 1
instance = &i
}
}
return instance
}
// 用于下边基准测试
func BenchmarkSprintf(b *testing.