go语言基础-sync.Once

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档


前言

package main
import (
   "fmt"
   "sync"
   "time"
   )
func main()  {
   var once sync.Once
   for i:=0;i<10;i++{
      go once.Do(func(){
         fmt.Println("fasfa")
      })
   }
   time.Sleep(time.Second*10)
}

一、介绍

sync.once是sync包中的一个对象,因为它只有一个方法DO,程序运行宏,无论被调用多少次,对于它来说只是执行一次即可。

二、使用场景

程序运行过程中,在会被多次调用的地方想执行一次某代码块,就可以全局声明一个once,然后可以只用它的方法once.Do()来执行代码。

1.源码

代码如下:

// Copyright 2009 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package sync

import (
	"sync/atomic"
)

// Once is an object that will perform exactly one action.
type Once struct {
	m    Mutex
	done uint32
}

// Do calls the function f if and only if Do is being called for the
// first time for this instance of Once. In other words, given
// 	var once Once
// if once.Do(f) is called multiple times, only the first call will invoke f,
// even if f has a different value in each invocation. A new instance of
// Once is required for each function to execute.
//
// Do is intended for initialization that must be run exactly once. Since f
// is niladic, it may be necessary to use a function literal to capture the
// arguments to a function to be invoked by Do:
// 	config.once.Do(func() { config.init(filename) })
//
// Because no call to Do returns until the one call to f returns, if f causes
// Do to be called, it will deadlock.
//
// If f panics, Do considers it to have returned; future calls of Do return
// without calling f.
//
func (o *Once) Do(f func()) {
	if atomic.LoadUint32(&o.done) == 1 {
		return
	}
	// Slow-path.
	o.m.Lock()
	defer o.m.Unlock()
	if o.done == 0 {
		defer atomic.StoreUint32(&o.done, 1)
		f()
	}
}

总结

从上面可以看到once结构体中,有两个字段,m是了保证并发安全性的,done是标志是否已经执行过此方法,如果done是1则表示执行过,0表示未执行。
Do方法中,首先通过atomic.LoadUint32(&o.done),来取得done的值,看是否为1,如果为1就表示已经执行过了,直接返回,未执行则继续执行。
代码很简单,就不啰嗦了,值得注意的是 defer atomic.StoreUint32(&o.done, 1)很精髓,为了防止f()方法中panic,无法为done赋值

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值