Go语言单例模式详解

 更新时间:2023年03月23日 08:59:50   作者:梧桐知秋  
本文主要介绍了Go语言单例模式详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧

单例模式是一种常见的设计模式,它在系统中仅允许创建一个实例来控制对某些资源的访问。在 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 对象来存储和获取数据。

总结

单例模式是一种常见的设计模式,它确保在系统中只存在唯一一个实例,并提供一个全局访问点。在 Go 语言中,实现单例模式有多种方式,包括懒汉式、饿汉式、双重检查锁定等。通过本文,我们了解了这几种实现方法的具体细节,并实现了一个数据缓存缓存的示例。

到此这篇关于Go语言单例模式详解的文章就介绍到这了,更多相关Go语言单例模式内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • Go外部依赖包从vendor,$GOPATH和$GOPATH/pkg/mod查找顺序

    Go外部依赖包从vendor,$GOPATH和$GOPATH/pkg/mod查找顺序

    这篇文章主要介绍了Go外部依赖包vendor,$GOPATH和$GOPATH/pkg/mod下查找顺序,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2020-12-12
  • golang中三种线程安全的MAP小结

    golang中三种线程安全的MAP小结

    在Go语言中,Map是并发不安全的,本文主要介绍了golang中三种线程安全的MAP小结,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2024-08-08
  • Go语言net包RPC远程调用三种方式http与json-rpc及tcp

    Go语言net包RPC远程调用三种方式http与json-rpc及tcp

    这篇文章主要为大家介绍了Go语言net包RPC远程调用三种方式分别使用http与json-rpc及tcp的示例详解,有需要的朋友可以借鉴参考下,希望能够有所帮助
    2021-11-11
  • 解决Golang小数float64在实际工程中加减乘除的精度问题

    解决Golang小数float64在实际工程中加减乘除的精度问题

    这篇文章主要介绍了解决Golang小数float64在实际工程中加减乘除的精度问题,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2021-03-03
  • 简单高效!Go语言封装二级认证功能实现

    简单高效!Go语言封装二级认证功能实现

    本文将介绍如何使用Go语言封装二级认证功能,实现简单高效的用户认证流程,二级认证是一种安全措施,要求用户在登录后进行额外的身份验证,以提高账户安全性,
    2023-10-10
  • 详解go语言中并发安全和锁问题

    详解go语言中并发安全和锁问题

    这篇文章主要介绍了go语言中并发安全和锁问题,包含互斥锁解锁过程,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2021-10-10
  • golang gc的内部优化详细介绍

    golang gc的内部优化详细介绍

    Go编译器在垃圾回收(GC)的扫描标记阶段,对存储无指针键值对的map进行了优化,即在GC扫描时不深入扫描map内部数据,只检查map本身是否需要回收,这一优化显著提升了GC扫描的速度,从而减少了GC对程序性能的影响
    2024-10-10
  • Go语言判断指定文件是否存在的方法

    Go语言判断指定文件是否存在的方法

    这篇文章主要介绍了Go语言判断指定文件是否存在的方法,实例分析了Go语言针对文件操作的技巧,具有一定参考借鉴价值,需要的朋友可以参考下
    2015-02-02
  • Go语言中websocket的使用demo分享

    Go语言中websocket的使用demo分享

    WebSocket是一种在单个TCP连接上进行全双工通信的协议。这篇文章主要和大家分享了一个Go语言中websocket的使用demo,需要的可以参考一下
    2022-12-12
  • Go语言之嵌入类型详解

    Go语言之嵌入类型详解

    本文详细讲解了Go语言之嵌入类型,文中通过示例代码介绍的非常详细。对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2022-07-07

最新评论