Golang 并发原语 Sync Once

Once 保证操作只执行一次

  • 适用于一些单例、配置的加载等

内部数据结构

go 复制代码
type Once struct {
    done atomic.Uint32
    m    Mutex
}
  • done 用于标识操作是否已经完成只有01
  • m 互斥锁

核心方法

  • Do

    scss 复制代码
    func (o *Once) Do(f func()) {
        if o.done.Load() == 0 {
           o.doSlow(f)
        }
    }
    func (o *Once) doSlow(f func()) {
        o.m.Lock()
        defer o.m.Unlock()
        if o.done.Load() == 0 {
           defer o.done.Store(1)
           f()
        }
    }
  • 原子加载done值是否为0

  • 如果等于0说明f func()并没有被初始化

  • 进入doSlow方法

  • 加锁,然后再次原子加载done值是否为0。这里进行可一个double check,确保当前done的值没有被修改

  • 执行f func(),然后将done标记为1

once这个并发原底层代码非常简洁,也很好理解。

相关推荐
Cisyam4 分钟前
使用Bright Data API轻松构建LinkedIn职位数据采集系统
后端
float_六七4 分钟前
Spring Boot 3为何强制要求Java 17?
java·spring boot·后端
bobz96518 分钟前
ovs arp
后端
_風箏30 分钟前
SpringBoot【集成ElasticSearch 01】2种方式的高级客户端 RestHighLevelClient 使用(依赖+配置+客户端API测试源码
后端
用户214118326360236 分钟前
dify案例分享-零基础上手 Dify TTS 插件!从开发到部署免费文本转语音,测试 + 打包教程全有
后端
架构师沉默1 小时前
Java 开发者别忽略 return!这 11 种写法你写对了吗?
java·后端·架构
EndingCoder1 小时前
React 19 与 Next.js:利用最新 React 功能
前端·javascript·后端·react.js·前端框架·全栈·next.js
RainbowJie11 小时前
Gemini CLI 与 MCP 服务器:释放本地工具的强大潜力
java·服务器·spring boot·后端·python·单元测试·maven
ITMan彪叔1 小时前
Nodejs打包 Webpack 中 __dirname 的正确配置与行为解析
javascript·后端
用户89535603282201 小时前
告别重复,用Go泛型精简Gin代码
后端·gin