golang sync.Once用法
sync.Once能确保实例化对象Do方法在多线程环境只运行一次,内部通过互斥锁实现
Do方法
Once类型的Do方法只接收一个参数,参数的类型必须是func(),即无参数无返回的函数。该方法的功能并不是对每一种参数函数都只执行一次,而是只执行首次被调用时传入的那个函数,并且之后不会再执行任何参数函数。所以,如果有多个需要执行一次的函数,应该为它们每一个都分配一个sync.Once类型的值。
var once sync.Once
for i, v := range make([]string, 10) {
once.Do(func() {
t.Log("function 1")
})
}
for i := 0; i < 10; i++ {
once.Do(func() {
t.Log("function 2")
})
}
这段示例代码只会输出一次“function 1”
与init函数对比
sync.Once 是 Golang package 中使方法只执行一次的对象实现,作用与 init 函数类似。但也有所不同。
- init 函数是在文件包首次被加载的时候执行,且只执行一次
- sync.Onc 是在代码运行中需要的时候执行,且只执行一次
当一个函数不希望程序在一开始的时候就被执行的时候,我们可以使用 sync.Once 。
源码
sync.Once 使用变量 done 来记录函数的执行状态,使用 sync.Mutex 和 sync.atomic 来保证线程安全的读取 done 。
func (o *Once) Do(f func()) {
if atomic.LoadUint32(&o.done) == 0 {
// Outlined slow-path to allow inlining of the fast-path.
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()
}
}
实现中也用到了类似double check思想
golang sync.Once用法的更多相关文章
- golang 常量的用法
1.Golang常量的用法 //常量的用法 var num int num =9 //1.常量声明的时候必须赋值 const tax int = 0 //2.常量值是无法修改的 //tax = 10 ...
- Golang Sync.WaitGroup 使用及原理
Golang Sync.WaitGroup 使用及原理 使用 func main() { var wg sync.WaitGroup for i := 0; i < 10; i++ { wg.A ...
- Golang sync.WaitGroup的用法
0x01 介绍 经常会看到以下了代码: 12345678910111213 package main import ( "fmt" "time") func m ...
- golang sync.noCopy 类型 —— 初探 copylocks 与 empty struct
问题引入 学习golang(v1.16)的 WaitGroup 代码时,看到了一处奇怪的用法,见下方类型定义: type WaitGroup struct { noCopy noCopy ... } ...
- golang sync/atomic
刚刚学习golang原子操作处理的时候发现github上面一个比较不错的golang学习项目 附上链接:https://github.com/polaris1119/The-Golang-Standa ...
- Golang:sync.Map
由于map在gorountine 上不是安全的,所以在大量并发读写的时候,会出现错误. 在1.9版的时候golang推出了sync.Map. sync.Map 通过阅读源码我们发现sync.Map是通 ...
- golang sync包
sync 在golang 文档上,golang不希望通过共享内存来进行进程间的协同操作,而是通过channel的方式来进行,当然,golang也提供了共享内存,锁等机制进行协同操作的包: 互斥锁: M ...
- golang包time用法详解
在我们编程过程中,经常会用到与时间相关的各种务需求,下面来介绍 golang 中有关时间的一些基本用法,我们从 time 的几种 type 来开始介绍. 时间可分为时间点与时间段,golang 也不例 ...
- golang(11) 反射用法详解
原文链接:http://www.limerence2017.com/2019/10/14/golang16/ 反射是什么 反射其实就是通过变量动态获取其值和类型的一种技术,有些语言是支持反射的比如py ...
- golang sync.Cond条件变量的使用
cond.Wait()的操作实际上是对与cond绑定的锁先进行解锁,在等待通知:接收到通知后,会尝试加锁,加锁成功则唤醒否则继续等待通知: cond.Waite()前必须对关连锁加锁,否则panic ...
随机推荐
- /usr/bin/install: cannot create regular file `/usr/local/jpeg6/include/jconfig.h'
出现下列异常: /usr/bin/install -c -m 644 jconfig.h /usr/local/jpeg6/include/jconfig.h /usr/bin/install: ca ...
- gin websocket
gin 中使用websocket功能 go get github.com/gorilla/websocket var upgrader = websocket.Upgrader{ CheckOrigi ...
- SAP物料状态
物料状态控制当前物料是否可以生产.采购.设计等功能 设置路径:spro-->后勤常规-->物料主数据-->设置关键字段-->定义物料状态
- 【笔记】DDD实战课-人保架构欧创新
目录 开篇 学好DDD,你能做什么? 基础 领域驱动设计:微服务设计为什么要选择 DDD? DDD的两层设计 DDD与微服务的关系 领域.子域.核心域.通用域和支撑域:傻傻分不清? 领域和子域 核心域 ...
- rust在windows上编译成liunx可执行程序
一.rust编译文件 cargo build 或 cargo build --release 发布构建 二.安装 x86_64-unknown-liunx-musl target rustup tar ...
- 【C学习笔记】day1-2 输出乘法口诀表
#include<stdio.h> int main() { for (int m = 1; m <= 9; m++) for (int n = 1; n <= m; n++) ...
- OSP6部署流程
准备4台虚拟机,完成初始化 一.架构如下: Controller 控制节点 也可以复用为计算节点 192.168.6.11 Compute01 192.168.6.21 Compute02 ...
- git 代码强制回滚操作整理(线上线下一起)
线上代码强制回滚操作,这边整理了一下 1.到线上 执行 git reset --hard xxxxxxxxxxx(更新前的一个版本)2.本地执行 和上面一样 git reset --hard xxxx ...
- 那些年vue踩过的坑v-if渲染完dom重新渲染 获取dom问题
当查询完成是 加载chart图了, 因为 上面的 div 是v-if 还没来得级渲染 所以获取下面chart div 时 没有dom元素 报错了
- nacos2.1 新增配置发布失败。请检查参数是否正确
使用官方的docker部署方式,部署了一个单节点nacos server,部署完了后发布配置信息,报错"新增配置发布失败.请检查参数是否正确" 解决方法: 在nacos mysql ...