Go语言学习笔记—golang并发编程之原子操作


一 原子变量的引入

先看一个实例:

package main 
 
import ( 
    "fmt" 
    "sync" 
    "time" 
) 
 
var i = 100 
 
func add() {
    
    i++ 
} 
 
func sub() {
    
    i-- 
} 
 
func main() {
    
    for i := 0; i < 100; i++ {
    
        go add() 
        go sub() 
    } 
 
    time.Sleep(time.Second * 3) 
    fmt.Printf("i: %v\n", i) 
 
} 
 

运行结果:

i: 99

由于资源竞争的原因,当某一个goroutine在访问某个数据资源的时候,按照数值,已经判断好了条件,然后又被其他的goroutine抢占了资源,并修改了数值,等这个goroutine再继续访问这个数据的时候,数值已经不对了。

此时可以使用锁实现协程的同步:

package main 
 
import ( 
    "fmt" 
    "sync" 
    "time" 
) 
 
var i = 100 
var lock sync.Mutex 
 
func add() {
    
    lock.Lock() 
    i++ 
    lock.Unlock() 
} 
 
func sub() {
    
    lock.Lock() 
    i-- 
    lock.Unlock() 
} 
 
func main() {
    
    for i := 0; i < 100; i++ {
    
        go add() 
        go sub() 
    } 
 
    time.Sleep(time.Second * 3) 
    fmt.Printf("i: %v\n", i) 
 
} 

运行结果:

i: 100  

当我们想要对某个变量并发安全的修改,除了使用官方提供的 mutex,还可以使用 sync/atomic 包的原子操作,它能够保证对变量的读取或修改期间不被其他的协程所影响。atomic提供的原子操作能够确保任一时刻只有一个goroutine对变量进行操作,善用atomic能够避免程序中出现大量的锁操作。

下面使用原子操作:

package main 
 
import ( 
    "fmt" 
    "sync/atomic" 
    "time" 
) 
 
var i int32 = 100 
 
func add() {
    
    atomic
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值