Go语言单例模式详解

作者:梧桐知秋 时间:2024-01-30 08:42:41 

单例模式是一种常见的设计模式,它在系统中仅允许创建一个实例来控制对某些资源的访问。在 Go 语言中,实现单例模式有多种方式,本篇文章将带你深入掌握 Go 语言中的单例模式实现。

什么是单例模式

单例模式指仅允许创建一个对象的设计模式。它通常应用于控制对某些资源的访问,例如数据库连接、线程池等等。通过单例模式,可以确保系统中只存在唯一一个实例,并提供一个全局访问点,方便其他对象使用。

Go中实现单例模式的方式

Go 语言提供了多种方式来实现单例模式,包括以下几种方法:

方法一: 懒汉式

懒汉式是一种常见的单例模式实现方式,其特点是在首次使用时创建单例实例。实现方法如下:

package singleton

import "sync"

var (
instance *Singleton
once     sync.Once
)

type Singleton struct {
}

func GetInstance() *Singleton {
once.Do(func() {
instance = &Singleton{}
})

return instance
}

在上面的代码中,我们定义了一个名为 Singleton 的结构体,并将其实例化为 instance。同时,使用 sync 包中的 sync.Once 对象 once 实现在程序生命周期内只执行一次的逻辑。当第一次调用 GetInstance 时,Sync.Once 的 Do 方法会调用传入的函数,该函数的逻辑是实例化 Singleton 对象并赋值给 instance。在后续调用 GetInstance 时,由于 instance 已经被实例化,不会再次创建。

方法二:饿汉式

饿汉式是另一种常见的单例模式实现方式,其特点是在系统启动时即创建单例实例,当调用时直接返回该实例。实现方法如下:

package singleton

var instance *Singleton = &Singleton{}

type Singleton struct {
}

func GetInstance() *Singleton {
return instance
}

在上面的代码中,我们在包初始化时创建了一个 Singleton 对象并赋值为 instance。GetInstace 方法直接返回该实例,因此每一次调用都返回同一个对象,达到了控制对象实例的目的。

方法三:双重检查锁定

双重检查锁定是一种在多线程环境下使用的单例模式实现方式,其特点是先检查是否已经有实例,如果没有则进入同步代码块进行创建。实现方法如下:

package singleton

import "sync"

var (
instance *Singleton
mu       sync.Mutex
)

type Singleton struct {
}

func GetInstance() *Singleton {
if instance == nil {
mu.Lock()
defer mu.Unlock()
if instance == nil {
instance = &Singleton{}
}
}
return instance
}

在上面的代码中,我们使用了互斥锁实现并发控制,确保在多线程环境下只有一个线程能够访问临界资源。同时,使用了一个双重检查机制,减少互斥锁使用的频率。

示例

通过下面的示例,我们可以了解如何使用单例模式来实现数据缓存。

package main

import (
"fmt"
"sync"
)

type Cache struct {
store map[string]string
mu    sync.Mutex
}

var instance *Cache

func GetCacheInstance() *Cache {
if instance == nil {
instance = &Cache{
store: make(map[string]string),
}
}
return instance
}

func (c *Cache) Get(key string) (string, bool) {
c.mu.Lock()
defer c.mu.Unlock()

val, ok := c.store[key]
return val, ok
}

func (c *Cache) Set(key, val string) {
c.mu.Lock()
defer c.mu.Unlock()

c.store[key] = val
}

func main() {
cache := GetCacheInstance()

cache.Set("name", "Tom")
if val, ok := cache.Get("name"); ok {
fmt.Println(val)
}
}

在上面的代码中,我们定义了一个 Cache 结构体,表示数据缓存。Cache 中包含了 Store 成员变量用于存储键值对,使用互斥锁 mu 控制访问。GetCacheInstance 函数返回一个 Cache 实例,表示数据缓存,在第一次调用时,会将 instance 实例化为一个 Cache 对象。示例中的 main 函数演示了如何使用单例的 Cache 对象来存储和获取数据。

来源:https://juejin.cn/post/7212776427166941221

标签:Go,单例模式
0
投稿

猜你喜欢

  • 7个perl数组高级操作技巧分享

    2022-08-09 10:38:19
  • python学习实操案例(二)

    2022-09-04 01:36:41
  • 分享:在存储过程中使用另一个存储过程返回的查询结果集的方法

    2024-01-16 13:03:57
  • Python数据处理之pd.Series()函数的基本使用

    2022-09-29 08:50:21
  • python 爬取吉首大学网站成绩单

    2023-08-02 05:57:13
  • python logging通过json文件配置的步骤

    2022-06-04 22:30:19
  • python3.6环境下安装freetype库和基本使用方法(推荐)

    2023-04-21 19:43:00
  • pytorch 实现情感分类问题小结

    2022-11-06 12:21:00
  • Python 日期的转换及计算的具体使用详解

    2023-01-06 11:31:27
  • Python面向对象编程基础解析(二)

    2023-11-16 01:53:23
  • Vue开发环境跨域访问问题

    2023-07-02 17:07:34
  • asp压缩access数据库(带密码)方法

    2007-09-06 19:48:00
  • Oracle中查看正在运行的SQL进程脚本分享

    2024-01-28 11:59:58
  • python3中rank函数的用法

    2022-09-26 07:00:45
  • python munch库的使用解析

    2023-11-26 01:42:20
  • 基于python分布式爬虫并解决假死的问题

    2021-06-28 03:38:28
  • php判断用户是否关注微信公众号

    2024-04-28 09:45:25
  • win10安装tensorflow-gpu1.8.0详细完整步骤

    2023-01-22 08:44:33
  • python中使用asyncio实现异步IO实例分析

    2021-02-06 10:02:50
  • Python+Opencv身份证号码区域提取及识别实现

    2021-10-01 17:32:13
  • asp之家 网络编程 m.aspxhome.com