单例模式
解决的问题
保证一个环境只有一个实例在运行。解决一个全局使用的类频繁的创建和销毁。
优点
- 内存中只有一个实例,减少内存开销
- 避免对资源的多重占用,比如写文件的操作
缺点
- 没有接口,不能继承。
代码实现
1. 懒汉模式
缺点:非线程安全,当正在创建时,如果有线程来访,Instance == nil时,会重复创建,就不是单例模式了。
type Singleton struct{}
var Instance *Singleton
func GetInstance() *Singleton {
if Instance == nil {
Instance = &Singleton{}
}
return Instance
}
2. 饿汉模式
缺点:如果Singleton结构体创建比较耗时,加载时间会很长。
type Singleton struct{}
var Instance2 *Singleton = &Singleton{}
func GetInstance2() *Singleton {
return Instance2
}
3. 带锁的懒汉模式
缺点:反复加锁会导致线程阻塞
var Instance3 *Singleton
var mut sync.Mutex
func GetInstance3() *Singleton {
mut.Lock()
defer mut.Unlock()
if Instance3 == nil {
Instance3 = &Singleton{}
}
return Instance3
}
4. 双重锁的懒汉模式
缺点:实现较复杂
优点: 性能提高
var Instance4 *Singleton
var mut2 sync.Mutex
func GetInstance4() *Singleton {
if Instance4 == nil {
mut2.Lock()
defer mut2.Unlock()
if Instance4 == nil {
Instance4 = &Singleton{}
}
}
return Instance4
}
5. Once实现懒汉模式
golang的sync包中,提供once锁once.Do(func(){})中的函数只会执行一次。这样的代码看上去也比较简洁。
var Instance5 *Singleton
var once sync.Once
func GetInstance5() *Singleton {
once.Do(func() {
Instance5 = &Singleton{}
})
return Instance5
}
有疑问加站长微信联系(非本文作者)