网站首页 > 文章精选 正文
单例模式(Singleton Pattern)是一种创建型设计模式,它确保一个类只有一个实例,并提供一个全局访问点来访问该实例。这种模式常用于需要全局唯一对象的场景,如配置管理、日志记录、数据库连接池等。
单例模式的特点
- 唯一性:确保一个类只有一个实例存在
- 全局访问:提供全局访问点,通常通过静态方法实现
- 延迟初始化:通常在第一次使用时才创建实例(懒加载)
Go 语言实现单例模式
在 Go 语言中,可以通过以下几种方式实现单例模式:
1. 使用 sync.Once 实现(推荐)
package main
import (
"fmt"
"sync"
)
type Logger struct {
}
func (l *Logger) Info(msg string) {
fmt.Printf(msg)
}
var (
once sync.Once
logger *Logger
)
func GetLogger() Logger {
once.Do(func() {
logger = &Logger{}
fmt.Printf("init logger:\t %p \r\n", logger)
})
return *logger
}
func main() {
for i := 0; i < 10; i++ {
go func(i int) {
logger := GetLogger()
logger.Info(fmt.Sprintf("instance %d,\t %p \r\n", i, &logger))
}(i)
}
fmt.Scanln()
}
2. 使用互斥锁实现(线程安全)
package main
import (
"fmt"
"sync"
)
type Singleton struct {
// 单例属性
}
var (
instance *Singleton
mu sync.Mutex
)
func GetInstance() *Singleton {
if instance == nil {
mu.Lock()
defer mu.Unlock()
// 再次检查,防止在获取锁之前其他goroutine已经创建了实例
if instance == nil {
instance = &Singleton{}
fmt.Println("Creating single instance now.")
}
}
return instance
}
func main() {
for i := 0; i < 5; i++ {
go GetInstance()
}
fmt.Scanln()
}
3. 包级变量实现(最简单,但不支持延迟初始化)
package main
import "fmt"
type Singleton struct {
// 单例属性
}
var instance = &Singleton{}
func GetInstance() *Singleton {
return instance
}
func main() {
instance1 := GetInstance()
instance2 := GetInstance()
if instance1 == instance2 {
fmt.Println("Both instances are the same.")
}
}
单例模式的应用场景
- 配置管理:全局配置对象只需要一个实例
- 日志记录:日志记录器通常只需要一个实例
- 数据库连接池:维护一个全局的连接池实例
- 缓存系统:全局缓存管理器
- 线程池:管理应用程序中的线程资源
注意事项
- 并发安全:在多线程/多goroutine环境下,确保单例的创建是线程安全的
- 测试困难:单例模式可能使单元测试变得困难,因为它保持了全局状态
- 隐藏依赖:单例的使用可能导致代码的依赖关系不明显
在 Go 语言中,推荐使用 sync.Once 来实现单例模式,因为它简洁且高效地解决了并发安全问题。
- 上一篇: Go语言泛型-泛型对代码结构的优化
- 下一篇: Go语言零到一:控制流(go语言工作流)
猜你喜欢
- 2025-07-14 Go并发编程之WaitGroup(go语言 并发)
- 2025-07-14 golang企业微信告警(企业微信告警推送)
- 2025-07-14 2.8 Go语言中的for循环,break和continue
- 2025-07-14 Go语言Context包:最常用包之一的使用指南
- 2025-07-14 Go语言零到一:动态数组——切片(go语言的切片)
- 2025-07-14 2025-06-26:转换数组。用go语言,给你一个整数数组 nums,它被视
- 2025-07-14 go sync.Pool简介(go system)
- 2025-07-14 2025-07-13:统计特殊子序列的数目。用go语言,给定一个只包含正
- 2025-07-14 Go语言数据库编程:GORM 的基本使用
- 2025-07-14 2025-06-28:长度可被 K 整除的子数组的最大元素和。用go语言,给
- 最近发表
- 标签列表
-
- newcoder (56)
- 字符串的长度是指 (45)
- drawcontours()参数说明 (60)
- unsignedshortint (59)
- postman并发请求 (47)
- python列表删除 (50)
- 左程云什么水平 (56)
- 编程题 (64)
- postgresql默认端口 (66)
- 数据库的概念模型独立于 (48)
- 产生系统死锁的原因可能是由于 (51)
- 数据库中只存放视图的 (62)
- 在vi中退出不保存的命令是 (53)
- 哪个命令可以将普通用户转换成超级用户 (49)
- noscript标签的作用 (48)
- 联合利华网申 (49)
- swagger和postman (46)
- 结构化程序设计主要强调 (53)
- 172.1 (57)
- apipostwebsocket (47)
- 唯品会后台 (61)
- 简历助手 (56)
- offshow (61)
- mysql数据库面试题 (57)
- fmt.println (52)