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

相关推荐
遨翔在知识的海洋里2 小时前
nest(3)-jwt和RBAC
后端
遨翔在知识的海洋里2 小时前
nest(5)-Middleware
后端
程序员梅雨2 小时前
Linux & Shell 实用干货
linux·运维·服务器·后端·面试·php
大牧师2 小时前
TypeORM 入门教程
后端·sql·mysql·orm·nest·typeorm
IT_陈寒2 小时前
Vite静态资源路径这个大坑害我调了一下午
前端·人工智能·后端
oliver_sys_log3 小时前
绕过 Yearning 查询体验限制:我做了一个 DataGrip 只读 SQL 代理
后端·mysql
水深火乐3 小时前
golang-jwt v5 入门
后端
carson9553 小时前
基于springboot和vue的文本文件上传下载在线编辑功能
后端
n8n3 小时前
Spring AI 提示词工程进阶:System / User / Assistant 角色、Prompt Template 动态拼装与多角色人设切换
后端
步行cgn3 小时前
Spring Boot 主入口类上的 @Enable 和 @Scan 注解详解
java·spring boot·后端