单例模式-go语言实现
一、理论知识
单例设计模式(Singleton Design Pattern)是指一个对象只允许被实例化一次,并提供一个访问该实例的全局访问点。
应用场景:
- 避免资源访问冲突,例如写日志文件操作;
- 表示业务概念上的全局唯一类,例如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 }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· AI技术革命,工作效率10个最佳AI工具