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这个并发原底层代码非常简洁,也很好理解。

相关推荐
River41611 分钟前
Javer 学 c++(十三):引用篇
c++·后端
一直_在路上17 分钟前
Go 语言微服务演进路径:从小型项目到企业级架构
架构·go
RoyLin19 分钟前
TypeScript设计模式:迭代器模式
javascript·后端·node.js
爱海贼的无处不在1 小时前
一个需求竟然要开14个会:程序员的日常到底有多“会”?
后端·程序员
IT_陈寒2 小时前
Java 性能优化:5个被低估的JVM参数让你的应用吞吐量提升50%
前端·人工智能·后端
南囝coding2 小时前
《独立开发者精选工具》第 018 期
前端·后端
绝无仅有2 小时前
数据库MySQL 面试之死锁与排查经验总结
后端·面试·github
用户384958730692 小时前
Spring Boot 集成 Redis 的完整流程
后端
昨日的风3 小时前
springboot 多数据源切换
后端