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 ...
随机推荐
- https原理(四)双向实践(java客户端+tcp代理)
本文采用客户端与服务端共用一个密钥对 1 将https代理服务器(三)实践中的mkcert p12分解为一个公钥一个私钥 mac@macdeMacBook mkcert % openssl pkcs1 ...
- Kafka Reblance & max.poll.interval.ms 重复消费问题
1. 什么是kafka Reblance 消费组是MQ中一个非常重要的概念,一个消费组监听一个Topic时,Kafka服务端会给消费组中的每一个实例,进行队列分配,每一个实例指定消费一个或多个队列(分 ...
- maven的setting.xml配置文件详解
<?xml version="1.0" encoding="UTF-8"?> <settings xmlns="http://mav ...
- select标签如何实现 每个option传递多个值
设计项目时 我们有时候会利用 <select> <option value="值1" > </option> </select> ...
- EasyExcel工具使用
pom文件: <dependency> <groupId>com.alibaba</groupId> <artifactId>easyexcel< ...
- Cplex-opl解决网络路由选择和资源分配问题
安装Cplex 注意事项:全英文系统.安装路径.代码,会减少软件运行设置错误.(该软件对中文支持性不好) opl语言基础 [转载]CPLEX学习笔记二 – OPL的数据类型 - 知乎 (zhihu.c ...
- egg开发系列--模板语法
在这里列一下 nunjucks 常用的模板内容 首先需要在plugin.js 当中引入 exports.nunjucks = { enable: true, package: 'egg-view-nu ...
- 理解cpu过高的逻辑思维与分析方法
工作经常碰到负载过高,cpu占有太高,系统变慢,运维通常做的第一件事就是通过top或者uptime命令来了解系统负载的情况 通常uptime后会出现三个小数,就是平均负载值,那真正的了解这个平均负载值 ...
- 打卡node day01--基础和fs内置模块
一, 检查 node 版本 node -v 或 node --version 二,检查安装过的node 版本(nvm node 版本管理工具 安装链接 参考百度) nvm ls 三,切换node 版 ...
- vue 移动端px转rem
1.安装lib-flexible 终端执行命令:npm i lib-flexible --save 2.在main.js引入lib-flexible 3.终端执行命令:npm install post ...