专栏首页后端golang 系列:sync.Once 讲解
原创

golang 系列:sync.Once 讲解

sync.Once 介绍

之前提到过 Go 的并发辅助对象:WaitGroup。同样的, sync.Once 也是 Go 官方的一并发辅助对象,它能够让函数方法只执行一次,达到类似 init 函数的效果。我们来看看它的简单用法:

func main() {
	var once sync.Once
	onceFunc := func() {
		fmt.Println("Only once")
	}

	for i := 0; i < 10; i++ {
		once.Do(onceFunc)
	}
}

这里执行后我们将只看到一次 Only once 的打印信息,这就是 sync.Once 的一次性效果。

sync.Once 源码

我们来看下 sync.Once 的源码:

type Once struct {
	done uint32
	m    Mutex
}

func (o *Once) Do(f func()) {
    // 原子加载标识值,判断是否已被执行过
	if atomic.LoadUint32(&o.done) == 0 {
		o.doSlow(f)
	}
}

func (o *Once) doSlow(f func()) { // 还没执行过函数
	o.m.Lock()
	defer o.m.Unlock()
	if o.done == 0 { // 再次判断下是否已被执行过函数
		defer atomic.StoreUint32(&o.done, 1) // 原子操作:修改标识值
		f() // 执行函数
	}
}

从上面可以分析出,sync.Once 是通过对一个标识值,原子性的修改和加载,来减少锁竞争的。


感兴趣的朋友可以搜一搜公众号「 阅新技术 」,关注更多的推送文章。

可以的话,就顺便点个赞、留个言、分享下,感谢各位支持!

阅新技术,阅读更多的新知识。

原创声明,本文系作者授权云+社区发表,未经许可,不得转载。

如有侵权,请联系 yunjia_community@tencent.com 删除。

关注作者,阅读全部精彩内容

我来说两句

0 条评论
登录 后参与评论

相关文章

  • golang 系列: mutex 讲解

    Go 号称是为了高并发而生的,在高并发场景下,势必会涉及到对公共资源的竞争。当对应场景发生时,我们经常会使用 mutex 的 Lock() 和 Unlock()...

    lincoln
  • Golang语言标准库 sync 包的 Once 怎么使用?

    在 Go 语言中,sync 包有一个 Once 类型,官方文档介绍 Once 是一个只执行一次操作的对象。所以,Once 一般用于并发执行,但只需初始化一次的共...

    frank.
  • golang框架解析-iris

    报了个驾校,时隔两个多月没发文章了,驾考上周终于都结束了,这之后得补补前两月的文章了。之前定了个目标,读完beego、iris、gin等go框架的源码,之前已经...

    用户1093396
  • golang 多协程的同步方法总结

    之前用 go 写一个小工具的时候, 用到了多个协程之间的通信, 当时随手查了查, 结果查出来一大坨, 简单记录一下. golang中多个协程之间是如何进行通信及...

    烟草的香味
  • Go语言源码笔记 --- netpoller

    总览:Go中网络交互采用多路复用的技术,具体到各个平台,即Kqueue、Epoll、Select、Poll等,下面以Linux下的Epoll实现为例进行分析。

    后台搬砖鹅
  • golang框架解析-iris

    报了个驾校,时隔两个多月没发文章了,驾考上周终于都结束了,这之后得补补前两月的文章了。之前定了个目标,读完beego、iris、gin等go框架的源码,之前已经...

    大愚
  • Golang并发编程控制

    重学编程之Golang的plan中的上一篇文章我向大家介绍了,并发编程基础,goroutine的创建,channel,正由于go语言的简洁性,我们可以简易快速的...

    PayneWu
  • Golang 编程思维和工程实战

    ? Golang 的一些编程思维和思想,以及总结一些常见的优雅编程实战技巧。 作者:allendbwu,腾讯 PCG 后台开发工程师 一 Golang 编程思...

    腾讯技术工程官方号
  • Kubernetes 源码学习之延时队列

    client-go 中的 workqueue,类似于 golang 语言中的 channel,主要用于并发程序之间的数据同步。Kubernetes 的控制器模型...

    我是阳明
  • golang 系列:context 详解

    在很多的 Go 开源框架里,我们经常能看到 context 的身影,它的使用场景有很多,像超时通知,取消通知都用到了 context。今天我们就来好好的认识一下...

    lincoln
  • golang 系列:waitgroup 解析

    Golang 提供了简洁的 go 关键字来让开发者更容易的进行并发编程,同时也提供了 WaitGroup 对象来辅助并发控制。今天我们就来分析下 WaitGro...

    lincoln
  • SDL系列讲解(四) demo讲解

    整体流程框架 SDL作为一款渲染器,我们首先掌握下它的一些基础要素,本文通过渲染一张图片,熟悉SDL的整个流程。 #include "SDL.h" 扩入我们...

    用户1263308
  • Go 语言并发编程系列(十三)—— sync 包系列:sync.WaitGroup 和 sync.Once

    在介绍通道的时候,如果启用了多个子协程,我们是这样实现主协程等待子协程执行完毕并退出的:声明一个和子协程数量一致的通道数组,然后为每个子协程分配一个通道元素,在...

    学院君
  • 聊聊golang的lumberjack

    Logger定义了Filename、MaxSize(单个文件大小最大值,单位M)、MaxAge(单位天)、MaxBackups、LocalTime、Compre...

    code4it
  • 聊聊golang的lumberjack

    Logger定义了Filename、MaxSize(单个文件大小最大值,单位M)、MaxAge(单位天)、MaxBackups、LocalTime、Compre...

    code4it
  • io事件中,g是怎么把事件交还给g0的呢?

    那么在io事件中,g是怎么把事件交还给g0的呢?这时候就牵扯到我们今天的主角----netpoll。

    用户7705674
  • golang 系列:channel 全面解析

    channel 是 goroutine 与 goroutine 之间通信的重要桥梁,借助 channel,我们能很轻易的写出一个多协程通信程序。今天,我们就来看...

    lincoln
  • SDL系列讲解(一) 简介

    什么是 SDL Simple DirectMedia Layer(SDL)是一个跨平台开发库,主要提供对音频,键盘,鼠标,操纵杆的操作,通过OpenGL和Di...

    用户1263308
  • vulhub系列课程1_4nth0ny讲解

    乌鸦安全的技术文章仅供参考,此文所提供的信息只为网络安全人员对自己所负责的网站、服务器等(包括但不限于)进行检测或维护参考,未经授权请勿利用文章中的技术资料对任...

    乌鸦安全

扫码关注云+社区

领取腾讯云代金券