首页 文章资讯内容详情

Golang 单例模式实现

2026-06-01 4 花语

本文内容纲要:

单例模式在开发中是一种相对简单的设计模式,但它在实现上又有很多种方式

熟悉java的同学知道在java中实现单例常见的有懒汉式、饿汉式、双重检查、内部静态类、枚举单例等(传送门)

而由于语言的特性,golang目前常见的有以下四种方式(懒汉式、饿汉式、双重检查、sync.Once)

1.懒汉式----非线程安全

非线程安全,即在多线程下可能会创建多次对象

/** *使用结构体代替类 */ typeToolstruct{ valuesint } /** *建立私有变量 */ varinstance*Tool /** *获取单例对象的方法,引用传递返回 */ funcGetInstance()*Tool{ ifinstance==nil{ instance=new(Tool) } returninstance }

2.懒汉式----线程安全

在非线程安全的基本上,利用Sync.Mutex进行加锁,保证线程安全,但由于每次调用该方法都进行了加锁操作,在性能上相对不高效

/** *锁对象 */ varlocksync.Mutex /** *加锁保证线程安全 */ funcGetInstance()*Tool{ lock.Lock() deferlock.Unlock() ifinstance==nil{ instance=new(Tool) } returninstance }

3.饿汉式

直接创建好对象,这样不需要判断为空,同时也是线程安全。唯一的缺点是在导入包的同时会创建该对象,并持续占有在内存中。

varinstanceTool funcGetInstance()*Tool{ return&instance }

4.双重检查

在懒汉式(线程安全)的基础上再进行忧化,判少加锁的操作。保证线程安全同时不影响性能

/** *锁对象 */ varlocksync.Mutex /** *第一次判断不加锁,第二次加锁保证线程安全,一旦对象建立后,获取对象就不用加锁了 */ funcGetInstance()*Tool{ ifinstance==nil{ lock.Lock() ifinstance==nil{ instance=new(Tool) } lock.Unlock() } returninstance }

5.sync.Once

通过sync.Once来确保创建对象的方法只执行一次

varoncesync.Once funcGetInstance()*Tool{ once.Do(func(){ instance=new(Tool) }) returninstance }

sync.Once内部本质上也是双重检查的方式,但在写法上会比自己写双重检查更简洁,以下是Once的源码

func(o*Once)Do(ffunc()){ //判断是否执行过该方法,如果执行过则不执行 ifatomic.LoadUint32(&o.done)==1{ return } //Slow-path. o.m.Lock() defero.m.Unlock() //进行加锁,再做一次判断,如果没有执行,则进行标志已经扫行并调用该方法 ifo.done==0{ deferatomic.StoreUint32(&o.done,1) f() } }

本文内容总结:

原文链接:https://www.cnblogs.com/wpnine/p/10426105.html