以下是本人在项目经常用到的用法与作用,具体详细介绍可以看详细文档:
http://www.topgoer.com/%E5%B9%B6%E5%8F%91%E7%BC%96%E7%A8%8B/%E5%8E%9F%E5%AD%90%E6%93%8D%E4%BD%9C%E5%92%8Catomic%E5%8C%85.html
单个指令同步操作
1、并发下,数值计数
var i int64
atomic.AddInt64(&i, 1)
2、并发下,数值赋值
var num int64
atomic.StoreInt64(&num, 222)
3、并发下,数值读取
var num int64
atomic.LoadInt64(&num)
4、并发下,状态变更
var statusCode int64
atomic.CompareAndSwapInt64(&statusCode, 0, 1)
5、并发下,字典map赋值读取
var m sync.Map
m.Store("name", "su")
m.Load("name")
指令集,同步操作
有时产生一个值,需要一系列指令处理,想要对这整个指令集同步,比如加载配置,这时就需要atomic.Value上场。
func Main(){
var con atomic.Value
con.Store(LoadConfig())
c := con.Load()
fmt.Println(c)
}
func LoadConfig() map[string]string {
fmt.Println("开始获取配置处理")
m := make(map[string]string)
time.Sleep(1 * time.Second)
/** 读取配置文件等处理*/
m["file"] = ""
fmt.Println("结束配置读取")
return m
}
我们来看一下,atomic.Value是否是同步一个指令块
func main(){
go LoadConfig("协程A,加载配置")
go LoadConfig("协程B,加载配置")
for {
}
}
协程A,加载配置
协程B,加载配置
结束配置读取
结束配置读取
可以看出在不使用Lock()下是同时进行的,但我们要求的是无锁化,加上atomic.Value试一下
func Main(){
var con atomic.Value
go con.Store(LoadConfig("协程A,加载配置"))
go con.Store(LoadConfig("协程B,加载配置"))
}
协程A,加载配置
结束配置读取
协程B,加载配置
结束配置读取
因为atomic是在底层实现同步的,不能中断,比系统实现的mutex等锁性能消耗低。
网友评论