一架梯子,一头程序猿,仰望星空!
Golang设计模式教程 > 内容正文

Golang单例模式


1. 什么是单例模式

单例模式是一种创建型设计模式,它保证一个类只有一个实例,并提供一个全局访问点以便于获取该实例。单例模式通常用于需要共享资源或控制访问某个实例的场景。

2. 单例模式的特点和优点

单例模式具有以下特点和优点:

  • 确保类只有一个实例对象
  • 提供全局访问点,方便外部代码获取该实例
  • 避免重复创建实例,节省系统资源

3. 单例模式的应用场景

单例模式适用于以下应用场景:

  • 日志记录器:在整个系统中只能有一个日志记录器,以保证日志不会被重复记录。
  • 数据库连接池:在高并发环境下,使用单例模式可以避免频繁创建和销毁数据库连接。

4. Golang中的单例模式实现

在Golang中,可以使用不同的方式实现单例模式。下面介绍了两种常见的实现方式。

4.1. 懒汉式和饿汉式两种实现方式

懒汉式单例模式是在第一次使用时创建实例对象,而饿汉式单例模式是在程序启动时就创建实例对象。

// 懒汉式单例模式实现
package singleton

type Singleton struct {
}

var instance *Singleton

func GetInstance() *Singleton {
    if instance == nil {
        instance = &Singleton{}
    }
    return instance
}

// 饿汉式单例模式实现
package singleton

type Singleton struct {
}

var instance *Singleton = &Singleton{}

func GetInstance() *Singleton {
    return instance
}

4.2. 单例模式线程安全问题

上述的懒汉式实现方式在多线程环境下可能会出现问题,因为多个线程可能同时进入 if instance == nil 的判断条件,从而创建出多个实例。

4.3. 使用sync.Once实现线程安全的单例模式

通过使用 sync.Once 来保证只有一个 goroutine 执行初始化代码,从而解决了线程安全问题。

// 使用sync.Once实现线程安全的单例模式
package singleton

import (
    "sync"
)

type Singleton struct {
}

var instance *Singleton
var once sync.Once

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

4.4. 使用sync.Mutex实现线程安全的延迟初始化单例模式

另一种线程安全的延迟初始化单例模式的实现方式是使用 sync.Mutex 来加锁,保证只有一个 goroutine 执行初始化操作。

// 使用sync.Mutex实现线程安全的延迟初始化单例模式
package singleton

import (
    "sync"
)

type Singleton struct {
}

var instance *Singleton
var mu sync.Mutex

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