golang 通过sync/atomic库来支持cpu和操作系统级别的原子操作。但是对要操作类型有如下要求

  • int32, int64,uint32, uint64,uintptr,unsafe包中的Pointer。不过,针对unsafe.Pointer类型,该包并未提供进行原子加法操作的函数

sync/atomic 提供的原子操作有

  • 加法(add), 比较并交换(compare and swap, 简称CAS),加载(load), 存储(store),交换(swap)

针对sync/atomic支持的类型,会有注入atomic.AddInt32这样的函数提供支持

import (
"fmt"
"sync/atomic"
) func main() {
var a uint32 = 10
atomic.AddUint32(&a, 1)
fmt.Println(a)
// uint32需要一个非负整数,uint32(int32(-1)), 会被编译器报错,需要一个中间变量b来绕过
b := int32(-1)
atomic.AddUint32(&a, uint32(b))
fmt.Println(a)
// ^uint32(n-1), n为要减去的数
// 整数在计算机以补码形式存在,这里的异或求出来的补码与b的补码相同
atomic.AddUint32(&a, ^uint32(3-1))
fmt.Println(a)
}

上面的代码有几个点需要注意:

  1. 传递给atomic.AddUint32函数的必须是指针类型。同理,unsafe.Pointer也是如此
  2. 对于atomic.AddUint64函数做原子减法,有两种方法,具体看代码

sync/atomic 比较并交换操作与交换操作的异同:

  • 比较并交换操作即CAS操作,是有条件的交换操作,只有在条件满足的情况下才会进行值的交换
func main() {
var a int32 = 0
go func() {
for {
fmt.Println(a)
// 当a == 10,就设置 a=0,并返回ture
if atomic.CompareAndSwapInt32(&a, 10, 0) {
fmt.Println("The second number has gone to zero.")
break
}
time.Sleep(time.Millisecond * 500)
}
}()
for {
a++
if a >10 {
break
}
time.Sleep(time.Millisecond * 600)
}
}

sync/automic.Value

  • sync/automic.Value相当于一个容器,可以被用来"原子地"存储和加载任意的值

atomic.Value使用事项

  • 不用初始化,声明后即可使用。有两个指针方法Store和Load
  • atomic.Value类型属于结构体类型,而结构体属于值类型,因此对该值的赋值,都会产生新的副本。
  • 不能存储nil。
  • 第一个存入的值类型,决定了后续atomic.Value可以存入的值

原子操作--sync/atomic的用法的更多相关文章

  1. golang sync/atomic

    刚刚学习golang原子操作处理的时候发现github上面一个比较不错的golang学习项目 附上链接:https://github.com/polaris1119/The-Golang-Standa ...

  2. 原子操作(atomic operation)

    深入分析Volatile的实现原理 引言 在多线程并发编程中synchronized和Volatile都扮演着重要的角色,Volatile是轻量级的synchronized,它在多处理器开发中保证了共 ...

  3. golang语言中sync/atomic包的学习与使用

    package main; import ( "sync/atomic" "fmt" "sync" ) //atomic包提供了底层的原子级 ...

  4. Java 并发系列之九:java 原子操作类Atomic(13个)

    1. 原子更新基本类型类 2. 原子更新数组 3. 原子更新引用 4. 原子更新属性 5. txt java 原子操作类Atomic 概述 java.util.concurrent.atomic里的原 ...

  5. java架构之路(多线程)原子操作,Atomic与Unsafe魔术类

    这次不讲原理了,主要是一些应用方面的知识,和上几次的JUC并发编程的知识点更容易理解. 知识回顾: 上次主要说了Semaphore信号量的使用,就是一个票据的使用,我们举例了看3D电影拿3D眼镜的例子 ...

  6. 探究Java如何实现原子操作(atomic operation)

    1. 让我们首先了解下java 中 Volatile 关键字 Volatile可实现java内存模型当中的可见性, java内存模型的可见性: 可见性,是指线程之间的可见性,一个线程修改的状态对另一个 ...

  7. C++11中的原子操作(atomic operation)

    所谓的原子操作,取的就是“原子是最小的.不可分割的最小个体”的意义,它表示在多个线程访问同一个全局资源的时候,能够确保所有其他的线程都不在同一时间内访问相同的资源.也就是他确保了在同一时刻只有唯一的线 ...

  8. C++11中的原子操作(atomic operation)(转)

    所谓的原子操作,取的就是“原子是最小的.不可分割的最小个体”的意义,它表示在多个线程访问同一个全局资源的时候,能够确保所有其他的线程都不在同一时间内访问相同的资源.也就是他确保了在同一时刻只有唯一的线 ...

  9. [Go] sync.Once 的用法

    sync.Once.Do(f func()) 是一个非常有意思的东西,能保证 once 只执行一次,无论你是否更换 once.Do(xx) 这里的方法,这个 sync.Once块 只会执行一次. pa ...

随机推荐

  1. 2018.11.17 codechef PRIMEDST(点分治+fft)

    传送门 fftfftfft一眼题(其实最先想到的是nttnttntt,wawawa了几次之后发现模数不够大果断弃疗写fftfftfft) 我们点分治统计答案的个数. 考虑现在已经统计出了到当前点的所有 ...

  2. awk 用法(转)

    原文:https://www.cnblogs.com/xudong-bupt/p/3721210.html awk是行处理器: 相比较屏幕处理的优点,在处理庞大文件时不会出现内存溢出或是处理缓慢的问题 ...

  3. C#和java的对比及总结

    1.Java里的AClass.class得到的Class<T>类的对象对应C#的typeof(AClass)得到的Type类型的对象:(但是C#如果要反射创建对象是用Type对象的Asse ...

  4. php输出语句

    看不懂? 抄一遍代码吧. echo 和 print 在 PHP 中有两个基本的输出方式: echo 和 print echo 和 print 区别: echo - 可以输出一个或多个字符串 print ...

  5. ArcGIS 关于Web_Mercator

    #小知识#EPSG,即 European Petroleum Standards Group 欧洲石油标准组织 在ArcGIS 10中Web Mercator有三种EPSG编号.他们分别是EPSG38 ...

  6. STS启动失败:Failed to load the JNI shared library

    版本位不一致 jdk 版本 ↓ eclipse 版本(%STS_HOME%/STS.ini)

  7. NSUserDefaults 添加与删除

    //NSUserDefaults会创建一个plist文件,内部存放一个字典    NSUserDefaults *userDefaults = [NSUserDefaults standardUser ...

  8. Simultaneous Localization and Mapping Technology Based on Project Tango

    Abstract: Aiming at the problem of system error and noise in simultaneous localization and mapping ( ...

  9. 23种设计模式(1)-Facade设计模式

    前记 曾经我遇见的一个需求是这样的,接口A有个方法void methodA(),类B需要实现接口A的methodA()方法,并且在类B中需要把methodA()方法内部处理逻辑获得的结果利用C类实例的 ...

  10. 两个jsp文件运行后弹出对话框 下载文件问题

    这个问题是两个jsp字符编码不一致的问题 如图所示 划线部分是要特别注意的地方 出错往往是这里 有时是“;”后面有无空格 如果login.jsp有 那么loginCheck.jsp也必须要有而且是同样 ...