单例模式-go语言实现

一、理论知识

单例设计模式(Singleton Design Pattern)是指一个对象只允许被实例化一次,并提供一个访问该实例的全局访问点。

应用场景:

  1. 避免资源访问冲突,例如写日志文件操作;
  2. 表示业务概念上的全局唯一类,例如ID生成器、配置信息、连接池类等;

优点:

  • 减少了内存开销,尤其是频繁地创建和销毁实例时
  • 避免对资源的重复占用,例如文件操作

缺点:

  • 对OOP特性不友好
    • 以id生成器为例,如果采用了单例模式,就违背了基于接口而非实现的设计原则,也就违背了广义上的抽象特性,如果某一天需要替换id生成器时,成本很大。
  • 单例会隐藏类之间的依赖关系
    • 单例类不需要显示创建、不需要依赖参数传递,如果代码关系复杂时,调用关系会被隐藏得很隐蔽。
  • 单例对代码拓展性不友好
    • 单例模式模式只能有一个对象实例,如果某一天需要在代码中创建两个或多个实例,改动代价就特别大。例如如果采用了单例连接池,后续需要改造成两个连接池,一个普通sql、一个慢sql。

二、代码实现

package a_singleton
import "sync"
type Singleton struct{}
var ins *Singleton
// GetInstanceLazy 懒汉式。非并发安全。
func GetInstanceLazy() *Singleton {
if ins == nil {
ins = &Singleton{}
}
return ins
}
// GetInstanceLazyWithLock 懒汉式加锁,并发安全,但是性能差
var mu sync.Mutex
func GetInstanceLazyWithLock() *Singleton {
mu.Lock()
defer mu.Unlock()
if ins == nil {
ins = &Singleton{}
}
return ins
}
// GetInstanceLazyWithDoubleCheck 懒汉式-双重检查。并发安全,性能ok。
// Java版该实现存在CPU指令重排序问题,需要volatile关键字禁止指令重排序
func GetInstanceLazyWithDoubleCheck() *Singleton {
if ins == nil {
mu.Lock()
defer mu.Unlock()
if ins == nil {
ins = &Singleton{}
}
}
return ins
}
// GetInstanceHungry 饿汉式
var insHungry *Singleton = &Singleton{}
func GetInstanceHungry() *Singleton {
return insHungry
}
// GetInstanceOnce 利用go自带并发工具sync.Once
var once sync.Once
func GetInstanceOnce() *Singleton {
once.Do(func() {
ins = &Singleton{}
})
return ins
}
posted @   🐫沙漠骆驼  阅读(65)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· AI技术革命,工作效率10个最佳AI工具
点击右上角即可分享
微信分享提示