答案:Go语言中sync/atomic包提供int32、int64等基础类型的原子操作,如Add、Load、Store、Swap和CompareAndSwap,适用于计数器、状态标志等简单共享变量场景,相比互斥锁更轻量高效;通过atomic.AddInt64实现并发安全计数器,用CompareAndSwap实现CAS逻辑可构建无锁算法,如一次性初始化,但复杂类型需间接处理,且不宜滥用CAS导致逻辑混乱。

在Go语言中,sync/atomic 包提供了对基本数据类型的原子操作支持,能够避免多个goroutine同时访问共享变量时出现竞态条件。相比互斥锁(mutex),原子操作更轻量,适用于简单的共享变量读写场景,比如计数器、状态标志等。
注意: atomic包只支持以下几种基础类型:
对于结构体或复杂类型,不能直接使用原子操作,需通过指针或其他方式间接处理。
以 int64 为例,atomic 提供了几个核心函数:
立即学习“go语言免费学习笔记(深入)”;
下面是一个并发安全的计数器示例:
package main
import (
"fmt"
"sync"
"sync/atomic"
)
func main() {
var counter int64
var wg sync.WaitGroup
for i := 0; i < 10; i++ {
wg.Add(1)
go func() {
defer wg.Done()
for j := 0; j < 1000; j++ {
atomic.AddInt64(&counter, 1)
}
}()
}
wg.Wait()
fmt.Println("最终计数:", atomic.LoadInt64(&counter))
}
在这个例子中,多个goroutine同时对 counter 进行递增,使用 atomic.AddInt64 和 atomic.LoadInt64 确保操作的原子性,避免了使用 mutex 的开销。
Compare-And-Swap(CAS)是实现无锁算法的核心。例如,可以用它来实现一个只执行一次的操作(类似 sync.Once):
var initialized int32
var config map[string]string
func setup() {
if atomic.LoadInt32(&initialized) == 0 {
atomic.CompareAndSwapInt32(&initialized, 0, 1)
config = make(map[string]string)
config["mode"] = "prod"
}
}
这里先判断是否初始化,再通过 CAS 设置状态,确保只初始化一次。虽然 sync.Once 更推荐用于此场景,但 CAS 提供了更大的灵活性。
基本上就这些。只要涉及共享变量的简单读写,优先考虑 atomic,性能更高,代码也更清晰。关键是记住:不要对非原子类型做原子操作,也不要滥用CAS导致逻辑复杂。
以上就是Golang如何使用sync/atomic实现原子操作的详细内容,更多请关注php中文网其它相关文章!
每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号