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

相关推荐
码农BookSea4 小时前
ReAct:让大模型学会边想边做
后端·ai编程
码农BookSea5 小时前
10分钟掌握 JSON-RPC 协议,面试加分、设计不踩坑
后端
凤年徐5 小时前
C++手撕红黑树:从0到200行,拿下STL map底层核心
c++·后端·算法
IT_陈寒5 小时前
Python的列表推导式里藏了个坑,差点让我加班到凌晨
前端·人工智能·后端
卷无止境6 小时前
podman与docker的区别和生产环境最佳实践
后端
程途知微6 小时前
ConcurrentHashMap线程安全实现原理全解析
java·后端
Mars酱6 小时前
1分钟编写贪吃蛇 | JSnake贪吃蛇单机版
java·后端·开源
卷卷说风控6 小时前
养了10年风控,今年开始养「虾」了
后端
王码码20357 小时前
Go语言中的Elasticsearch操作:olivere实战
后端·golang·go·接口
Tomhex7 小时前
Go语言import用法详解
golang·go