atomic包提供了底层的原子级内存操作,对于同步算法的实现很有用。
atomic原子操作主要用于并发环境下,无须加锁对整数进行安全的加减、比较、读取操作。
atomic原子操作支持的数据类型:
- int32
- int64
- Uint32
- Uint64
1.例子
// 访问量计数
var count int64 = 0
// 对count变量进行原子加 1
// 原子操作可以在并发环境安全的执行
atomic.AddInt64(&count, 1)
// 对count变量原子减去10
atomic.AddInt64(&count, -10)
// 原子读取count变量的内容
pv := atomic.LoadInt64(&count)
2.atomic常用函数
2.1. LoadInt32
函数定义:
func LoadInt32(addr *int32) (val int32)
LoadInt32原子性的获取*addr的值。
LoadInt64,LoadUint32,LoadUint64序列函数用法类似,区别就是数据类型不同。
例子:
var count int32 = 0
// 原子读取count变量的内容
pv := atomic.LoadInt32(&count)
2.2. StoreInt32
函数定义:
func StoreInt32(addr *int32, val int32)
StoreInt32原子性的将val的值保存到*addr。
StoreInt64、StoreUint32、StoreUint64序列函数用法类似,区别就是数据类型不同
例子:
var count int32 = 0
// 安全的将100保存到count变量中
atomic.StoreInt32(&count, 100)
2.3. AddInt32
函数定义:
func AddInt32(addr *int32, delta int32) (new int32)
AddInt32原子性的将delta的值添加到*addr并返回新值。
AddInt64、AddUint32、AddUint64序列函数用法类似,区别就是数据类型不同
AddXXX 系列函数实现加法操作,在原子性上等价于:
*addr += delta
return *addr
例子:
var count int32 = 0
// 对count变量进行原子加 1, 并且返回新值
newCount := atomic.AddInt32(&count, 1)
2.4. SwapInt32
函数定义:
func SwapInt32(addr *int32, new int32) (old int32)
SwapInt32原子性的将新值保存到*addr并返回旧值。
SwapInt64、SwapUint32、SwapUint64序列函数用法类似,区别就是数据类型不同。
SwapXXX序列函数操作在原子性上等价于:
old = *addr
*addr = new
return old
例子:
var count int32 = 0
// 将200保存到count中, 并且返回旧的值
oldCount := atomic.SwapInt32(&count, 200)
2.5. CompareAndSwapInt32
函数定义:
func CompareAndSwapInt32(addr *int32, old, new int32) (swapped bool)
CompareAndSwapInt32原子性的比较addr和old,如果相同则将new赋值给addr并返回真。
CompareAndSwapInt64、CompareAndSwapUint32、CompareAndSwapUint64序列函数用法类似,区别就是数据类型不同。
CompareAndSwapXXX系列函数实现的比较-交换操作,在原子性上等价于:
if *addr == old {
*addr = new
return true
}
return false
例子:
var count int32 = 0
// 如果count变量的值为0,才将100保存到变量中,保存成功返回true,反之false
ok := atomic.CompareAndSwapInt32(&count, 0, 100)