Golang设计模式之单例模式

单例模式

单例模式是一种创建型设计模式,它确保一个类只有一个实例,并提供一个全局访问点。这种模式常用于管理共享资源,如配置信息、线程池、缓存等。

单例模式的角色

  • 单例(Singleton)角色:单例类负责创建自己的实例,并提供一个访问该实例的全局访问点。

Go示例

下面是一个使用Go语言实现的单例模式示例。我们将创建一个简单的配置管理器,它将作为单例使用。

package main

import (
	"fmt"
	"sync"
)

// 单例类型
type ConfigManager struct {
	ConfigData map[string]string
	sync.Mutex
}

// 实例变量,初始化为nil
var instance *ConfigManager

// 锁变量,用于双重检查锁定
var mutex sync.Mutex

// GetInstance 获取单例实例
func GetInstance() *ConfigManager {
	// 第一次检查,避免在多重赋值时产生竞争条件
	if instance == nil {
		mutex.Lock()
		// 第二次检查,确保在锁的保护下只有一个实例被创建
		if instance == nil {
			instance = &ConfigManager{
				ConfigData: make(map[string]string),
			}
		}
		mutex.Unlock()
	}
	return instance
}

func main() {
	// 获取单例实例
	configManager := GetInstance()
	configManager.Lock()
	configManager.ConfigData["key"] = "value"
	configManager.Unlock()

	// 获取单例实例并尝试修改数据
	newConfigManager := GetInstance()
	newConfigManager.Lock()
	if val, ok := newConfigManager.ConfigData["key"]; ok {
		fmt.Println("Config value:", val)
	}
	newConfigManager.Unlock()
}

我们定义了一个ConfigManager结构体,它包含了配置数据。我们使用了一个全局变量instance来存储单例实例,并使用了一个mutex来确保在多线程环境下只创建一个实例。

GetInstance函数用于获取单例实例。如果instancenil,它将锁定mutex,再次检查instance是否为nil,如果仍然为nil,则创建一个新的ConfigManager实例。这样可以确保即使在多线程环境下,也只有一个实例被创建。

main函数中,我们通过GetInstance获取单例实例,并对其进行操作。由于ConfigManager是单例的,所以所有通过GetInstance获取的实例都将是同一个实例。

Go语言中实现单例模式,确保全局只有一个实例,并提供了一个全局访问点。这种模式在管理共享资源时非常有用。

打 赏