Golang 并发原语 Sync Once

Once 保证操作只执行一次

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

内部数据结构

go 复制代码
type Once struct {
    done atomic.Uint32
    m    Mutex
}
  • done 用于标识操作是否已经完成只有0或1
  • 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这个并发原底层代码非常简洁,也很好理解。

相关推荐
一条小小yu2 分钟前
为什么使用springboot
java·spring boot·后端
香瓜子rd24 分钟前
MySQL InnoDB 并发控制核心原理:事务、隔离级别、MVCC 与锁机制
数据库·后端
RISCV_Explorer28 分钟前
RISC-V RVV向量编程模型机制解析——vsetvl配置、掩码与尾元素策略及长度无关编程
后端·risc-v
对象存储与RustFS35 分钟前
升级 RustFS 二进制不停机:一条一条换,留一条退路
后端·rust·开源
hasty39 分钟前
限制写了却没生效:OpenTelemetry Go 的 Unicode 截断边界
开发语言·后端·golang
JWASX2 小时前
Java 转 go 学习 - 项目管理
go
SensorFlow3 小时前
看板有漏斗阶段,为什么转化率仍可能是假的?用 ClickHouse 检查演示埋点
后端
LucianaiB3 小时前
【TextIn xParse 与 Workbuddy实践】我把答辩材料丢给 AI 审了一遍,它开始追着我要证据
后端
王中阳Go4 小时前
读者问"你用的什么 Agent":3 个 AI 员工的分工表和工具链
人工智能·后端·ai编程
BadQiang4 小时前
Java 调用 Python 服务,报错后该从哪里查起?
后端