当前位置:网站首页>golang源码分析(5):sync.Once
golang源码分析(5):sync.Once
2022-08-02 16:49:00 【用户9710217】
sync.once可以控制函数只能被调用一次,不能多次重复调用。
我们可以用下面的代码实现一个线程安全的单例模式
package singleton
import (
"fmt"
"sync"
)
type object struct {
name string
}
var once sync.Once
var obj *object //单例指针
//公开方法 外包调用
func Instance() *object {
once.Do(getObj)
return obj
}
func getObj() {
if obj == nil {
obj = new(object)
//可以做其他初始化事件
}
}
//单例测试
func (obj *object) Test() {
fmt.Println(obj.name)
}如果我们要自己实现这么一个功能如何做呢?
- 定义一个status变量用来描述是否已经执行过了
- 使用sync.Mutex 或者sync.Atomic实现线程安全的获取status状态, 根据状态判断是否执行特定的函数
然后看下sync.Once实际是如何实现的
// Once is an object that will perform exactly one action.
type Once struct {
m Mutex
done uint32
}
//使用了双层检查机制
func (o *Once) Do(f func()) {
if atomic.LoadUint32(&o.done) == 1 {
return
}
// Slow-path.
o.m.Lock()
defer o.m.Unlock()
//这里需要再次重新判断下,因为 atomic.LoadUint32取出状态值到 o.m.Lock() 之间是有可能存在其它gotoutine改变status的状态值的
if o.done == 0 {
f()
atomic.StoreUint32(&o.done, 1)
}
}也有网友写出了更简洁的代码,不知道官方为什么没有采用下面的实现方式。
type Once struct {
done int32
}
func (o *Once) Do(f func()) {
if atomic.LoadInt32(&o.done) == 1 {
return
}
// Slow-path.
if atomic.CompareAndSwapInt32(&o.done, 0, 1) {
f()
}
}边栏推荐
- 特殊变量 (SQL)
- uniapp引入vantUI库
- js实现改变原来对象中的键值对对应的值
- Mysql应用安装后找不到my.ini文件
- Gartner released, annual Challenger!
- 周末看点回顾|亚马逊将于2023年底关闭Amazon Drive网盘服务;千寻位置发布时空智能六大底层自研技术…
- CNN经典模型汇总[通俗易懂]
- 什么是实时流引擎?
- What is an APS system?What should I pay attention to when importing APS?Worth watching again and again
- Arduino hardware programming introduction to language learning
猜你喜欢
![js商品总价格、最高价格商品、排除重复商品[初版]](/img/6f/11241f0d717b0c4e163986ba76fe0b.png)
js商品总价格、最高价格商品、排除重复商品[初版]

navicat creates a connection 2002-can't connect to server on localhost (10061) and the mysql service has started the problem

Antd-ProComponents中的EditableProTable无法在子行继续新增子子行的临时解决方案

持续集成(四)Jenkins配置报警机制

领导无线边缘AI的联合神经形态学习,具有较高的识别精度以及较低的能耗

内网渗透之kerberos认证(三)

Nacos环境隔离

Pytest study notes

数字孪生园区场景中的坐标知识

Oracle 11g rac打完补丁,dbca新建数据库还需要执行应用补丁的sql吗?
随机推荐
Continuous integration (4) Jenkins configuration alarm mechanism
几种常见的跨域解决方法
【二】通过props进行传值,子页面多种方式接收
LeetCode·76.最小覆盖子串·滑动窗口
npm install报gyp info it worked if it ends with ok
Pytest study notes
Arduino 硬件编程语言基础学习入门
尚硅谷尚品项目汇笔记(三)
【电子器件笔记6】三极管(BJT)参数和选型
Timestamp formatting "recommended collection"
1.NVIDIA Deepstream开发指南中文版--欢迎使用 DeepStream 文档
特殊变量 (SQL)
智能合约安全——delegatecall (1)
QACTION_QAWiki
【C语言刷题】指针入门三题|字符串长度、字符串复制、两数交换
JWT原理详解_电磁感应现象原理
DeepMind 首席科学家 Oriol Vinyals 最新访谈:通用 AI 的未来是强交互式元学习
Redis的介绍和使用
开始使用 NVIDIA Jetson Orin 上的深度学习加速器
“蔚来杯“2022牛客暑期多校训练营4 E - Jobs (Hard Version)