Golang实现创建模式-单例模式(饿汉式、懒汉式、双重检查锁、单例枚举)
内容说明
单例模式解决的问题是确保一个类只有一个实例,并提供全局访问点,以避免多个对象之间的冲突和资源浪费。这种模式通常用于管理共享资源,例如数据库连接池或线程池。
本文实现了四种不同类型的单例模式:饿汉式、懒汉式、双重检查锁和枚举
为了汇总测试,通过Main方法创建两个实例来检查它们是否是同一个对象
package main
import (
"fmt"
"sync"
)
// 饿汉式单例模式
type HungrySingleton struct{
}
var hungrySingleton *HungrySingleton = &HungrySingleton{
}
// GetHungrySingleton 获取饿汉式单例
func GetHungrySingleton() *HungrySingleton {
return hungrySingleton
}
// LazySingleton 懒汉式单例模式
type LazySingleton struct{
}
var lazySingleton *LazySingleton
var once sync.Once
// GetLazySingleton 获取懒汉式单例
func GetLazySingleton() *LazySingleton {
once.Do(func() {
lazySingleton = &LazySingleton{
}
})
return lazySingleton
}
// DoubleCheckLockSingleton 双重检查锁单例模式
type DoubleCheckLockSingleton struct{
}
var doubleCheckLockSingleton *DoubleCheckLockSingleton
var lock sync.Mutex
// GetDoubleCheckLockSingleton 获取双重检查锁单例
func GetDoubleCheckLockSingleton() *DoubleCheckLockSingleton {
if doubleCheckLockSingleton == nil {
lock.Lock()
defer lock.Unlock()
if doubleCheckLockSingleton == nil {
doubleCheckLockSingleton = &DoubleCheckLockSingleton{
}
}
}
return doubleCheckLockSingleton
}
// SingletonEnum 单例枚举
type SingletonEnum int
const (
Instance1 SingletonEnum = iota
Instance2
Instance3
)
var instance = [...]SingletonEnum{
Instance1, Instance2, Instance3}
// String 获取单例枚举的字符串表示
func (s SingletonEnum) String() string {
switch s {
case Instance1:
return "Instance1"
case Instance2:
return "Instance2"
case Instance3:
return "Instance3"
default:
return "Unknown"
}
}
func main() {
hungrySingleton := GetHungrySingleton()
fmt.Println(hungrySingleton)
lazySingleton := GetLazySingleton()
fmt.Println(lazySingleton)
doubleCheckLockSingleton := GetDoubleCheckLockSingleton()
fmt.Println(doubleCheckLockSingleton)
for _, instance := range instance {
fmt.Println(instance)
}
}
饿汉模式
饿汉式初始化在类加载时创建单例类的实例。这确保了实例始终可用且线程安全,但如果实例不总是需要,则可能会浪费资源。
// 饿汉式单例模式
type HungrySingleton struct{
}
var hungrySingleton *HungrySingleton = &HungrySingleton{
}
// GetHungrySingleton 获取饿汉式单例
func GetHungrySingleton() *HungrySingleton {
return hungrySingleton
}
懒汉模式
懒汉式初始化仅在需要时创建单例类的实例。这样可以节省资源,但如果没有同步,则不是线程安全的。
// LazySingleton 懒汉式单例模式
type LazySingleton struct{
}
var lazySingleton *LazySingleton
var once sync.Once
// GetLazySingleton 获取懒汉式单例
func GetLazySingleton() *LazySingleton {
once.Do(func() {
lazySingleton = &LazySingleton{
}
})
return lazySingleton
}
双重检查锁
双重检查锁是懒汉式初始化的线程安全版本,它避免了在创建实例后的第一次同步。
// DoubleCheckLockSingleton 双重检查锁单例模式
type DoubleCheckLockSingleton struct{
}
var doubleCheckLockSingleton *DoubleCheckLockSingleton
var lock sync.Mutex
// GetDoubleCheckLockSingleton 获取双重检查锁单例
func GetDoubleCheckLockSingleton() *DoubleCheckLockSingleton {
if doubleCheckLockSingleton == nil {
lock.Lock()
defer lock.Unlock()
if doubleCheckLockSingleton == nil {
doubleCheckLockSingleton = &DoubleCheckLockSingleton{
}
}
}
return doubleCheckLockSingleton
}
枚举单例
枚举单例模式是一种简单的线程安全单例模式
// SingletonEnum 单例枚举
type SingletonEnum int
const (
Instance1 SingletonEnum = iota
Instance2
Instance3
)
var instance = [...]SingletonEnum{
Instance1, Instance2, Instance3}
// String 获取单例枚举的字符串表示
func (s SingletonEnum) String() string {
switch s {
case Instance1:
return "Instance1"
case Instance2:
return "Instance2"
case Instance3:
return "Instance3"
default:
return "Unknown"
}
}