sync/atomic通过CPU指令提供整数和指针类型的原子操作,如Add、CompareAndSwap、Load、Store、Swap及Value类型,实现无锁并发安全,适用于计数器、标志位、配置更新等简单场景,性能优于sync.Mutex;而sync.Mutex适用于保护复杂数据结构或临界区含耗时操作的场景,两者选择需权衡操作复杂度与性能需求。

Golang的
sync/atomic
sync.Mutex
sync/atomic
atomic.
AddInt32
AddInt64
AddUint32
AddUint64
var counter int64 atomic.AddInt64(&counter, 1) // counter现在是1
CompareAndSwapInt32
CompareAndSwapInt64
CompareAndSwapUint32
CompareAndSwapUint64
CompareAndSwapPointer
true
false
var value int32 = 10 // 如果value当前是10,就把它设置为20 swapped := atomic.CompareAndSwapInt32(&value, 10, 20) // swapped为true, value为20 // 如果value当前是10(现在是20了),就把它设置为30 swapped = atomic.CompareAndSwapInt32(&value, 10, 30) // swapped为false, value仍为20
LoadInt32
LoadInt64
LoadUint32
LoadUint64
LoadPointer
LoadValue
var config atomic.Value
config.Store("initial_config")
loadedConfig := config.Load().(string) // loadedConfig为"initial_config"StoreInt32
StoreInt64
StoreUint32
StoreUint64
StorePointer
StoreValue
Load
var status int32 atomic.StoreInt32(&status, 1) // status现在是1
SwapInt32
SwapInt64
SwapUint32
SwapUint64
SwapPointer
var oldVal int64 = 5 // 将oldVal设置为10,并返回它原来的值5 previous := atomic.SwapInt64(&oldVal, 10) // previous为5, oldVal为10
Value
atomic.Value
Load()
Store()
sync/atomic
sync.Mutex
这问题问得好,因为很多时候我们写并发代码,第一反应就是上锁。但实际上,
sync/atomic
sync.Mutex
sync.Mutex
立即学习“go语言免费学习笔记(深入)”;
而
sync/atomic
我个人经验来看,当你只是想对一个计数器进行增减,或者更新一个配置指针,却用了
sync.Mutex
sync/atomic
sync.Mutex
CompareAndSwap
sync/atomic
CompareAndSwap
sync/atomic
你可以把它想象成一个守门员,你告诉他:“如果现在是A状态,就把门打开到B状态。”守门员会迅速检查,如果确实是A,他会立即打开到B,并告诉你“搞定!”。如果他发现已经不是A了(比如别人在他检查前已经改成了C),他会告诉你“不行,状态不对!”。
CAS的强大之处在于,它允许我们构建无锁(lock-free)或免锁(wait-free)的数据结构和算法。传统的锁机制,比如
sync.Mutex
举个例子,一个简单的原子计数器就可以用CAS来实现,尽管
atomic.AddInt64
当然,CAS也不是万能药。它可能会导致“ABA”问题(如果一个值从A变为B,又变回A,CAS会误以为没有发生变化),虽然在Go的标准库中,对于基本类型这通常不是大问题,但在构建复杂无锁结构时需要考虑。此外,频繁的CAS失败重试也可能导致“忙等”(busy-waiting),消耗CPU资源。但无论如何,理解CAS是深入理解现代并发编程的关键一步。
sync/atomic
sync.Mutex
在实际开发中,选择
sync/atomic
sync.Mutex
我通常会优先考虑
sync/atomic
atomic.AddInt64
atomic.StoreInt32
var requestCount int64 // 每次处理请求 atomic.AddInt64(&requestCount, 1)
atomic.Pointer
atomic.Value
type Config struct {
// ... 配置字段
}
var currentConfig atomic.Value // 存储 *Config
// 初始化
currentConfig.Store(&Config{/* ... */})
// 更新配置
newConfig := &Config{/* ... */}
currentConfig.Store(newConfig)
// 读取配置
cfg := currentConfig.Load().(*Config)sync/atomic
CompareAndSwap
反之,我会倾向于使用
sync.Mutex
map
slice
sync.Mutex
atomic
sync.Mutex
atomic
sync.Mutex
atomic
总结来说,
sync/atomic
sync.Mutex
sync.Mutex
sync/atomic
以上就是Golang的sync/atomic包提供了哪些原子操作以避免锁竞争的详细内容,更多请关注php中文网其它相关文章!
每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号