atomic.Load和atomic.Store用于多goroutine下安全读写共享变量,避免锁开销;适用于简单读写场景,如标志位或计数器,而复杂操作仍需互斥锁。

在Golang并发编程中,
atomic.Load
atomic.Store
原子操作适用于对单个变量的读写操作,保证这些操作的原子性,即不可中断性。
互斥锁(
sync.Mutex
atomic.Load
atomic.Store
当你需要读取一个共享变量的值,并且不希望在读取期间有其他goroutine修改它时,使用
atomic.Load
立即学习“go语言免费学习笔记(深入)”;
package main
import (
"fmt"
"sync/atomic"
"time"
)
var running int32 = 1
func main() {
go func() {
for {
if atomic.LoadInt32(&running) == 0 {
fmt.Println("Stopping worker...")
return
}
fmt.Println("Worker running...")
time.Sleep(time.Millisecond * 500)
}
}()
time.Sleep(time.Second * 3)
fmt.Println("Stopping program...")
atomic.StoreInt32(&running, 0)
time.Sleep(time.Second)
fmt.Println("Program stopped.")
}在这个例子中,
atomic.LoadInt32(&running)
running
当你需要更新一个共享变量的值,并且希望保证更新操作的原子性,防止出现中间状态时,使用
atomic.Store
package main
import (
"fmt"
"sync/atomic"
"time"
)
var counter int64
func main() {
for i := 0; i < 1000; i++ {
go func() {
for j := 0; j < 1000; j++ {
atomic.AddInt64(&counter, 1) // 使用atomic.AddInt64更简洁
}
}()
}
time.Sleep(time.Second * 2)
fmt.Println("Counter:", atomic.LoadInt64(&counter))
}这里,
atomic.AddInt64(&counter, 1)
counter
counter
atomic.Value
package main
import (
"fmt"
"sync/atomic"
"time"
)
type Config struct {
Value string
}
var config atomic.Value
func main() {
// 初始配置
initialConfig := Config{Value: "Initial Value"}
config.Store(initialConfig)
// 定期更新配置
go func() {
for i := 0; i < 5; i++ {
newConfig := Config{Value: fmt.Sprintf("Value %d", i)}
config.Store(newConfig)
fmt.Println("Updated config:", newConfig)
time.Sleep(time.Millisecond * 500)
}
}()
// 读取配置
for i := 0; i < 10; i++ {
currentConfig := config.Load().(Config)
fmt.Println("Current config:", currentConfig)
time.Sleep(time.Millisecond * 200)
}
}在这个例子中,
atomic.Value
Config
atomic
atomic.LoadInt32
atomic.StoreInt64
atomic.AddUint64
atomic.CompareAndSwap
虽然原子操作比互斥锁更轻量级,但它们仍然有一定的性能开销。在高并发、对性能要求非常苛刻的场景下,需要仔细评估原子操作带来的性能影响。在某些情况下,使用更复杂的并发模式,例如 channel,可能可以获得更好的性能。但channel会增加代码的复杂性。
原子操作只能保证单个变量的读写操作是原子的。对于需要原子地执行多个操作的场景,原子操作就无能为力了。这时,仍然需要使用互斥锁或者其他更高级的同步机制。例如,一个银行转账操作,需要同时更新两个账户的余额,这时就需要使用事务或者互斥锁来保证操作的原子性。
以上就是Golang并发编程中何时需要使用atomic.Load和atomic.Store的详细内容,更多请关注php中文网其它相关文章!
编程怎么学习?编程怎么入门?编程在哪学?编程怎么学才快?不用担心,这里为大家提供了编程速学教程(入门课程),有需要的小伙伴保存下载就能学习啦!
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号