代码示例
package main
import (
"fmt"
"sync"
"sync/atomic"
)
type Data struct {
num1 int64
num2 int64
}
func main() {
var wg sync.WaitGroup
data := Data{}
// 模拟多个协程并发读写操作
for i := 0; i < 5; i++ {
wg.Add(1)
go func() {
defer wg.Done()
// 原子写操作
atomic.StoreInt64(&data.num1, int64(i))
atomic.StoreInt64(&data.num2, int64(i*2))
// 原子读操作
num1 := atomic.LoadInt64(&data.num1)
num2 := atomic.LoadInt64(&data.num2)
fmt.Printf("num1: %d, num2: %d\n", num1, num2)
}()
}
wg.Wait()
}
原子操作优势
- 保证数据一致性:原子操作可以确保在并发环境下,对共享数据的读写操作是原子的,不会出现数据竞争,从而保证数据的一致性。
- 性能提升:相比于使用锁机制,原子操作通常具有更高的性能。因为锁机制会导致线程或协程的阻塞,而原子操作不会。
- 简单易用:原子操作提供了简单的API,不需要复杂的锁管理逻辑,降低了编程的复杂性。
原子操作局限性
- 操作类型有限:原子操作通常只支持一些基本的数据类型,如整数、指针等,对于复杂的数据结构,原子操作可能无法直接适用。
- 功能局限性:原子操作只能保证单个操作的原子性,对于涉及多个原子操作的复杂逻辑,可能无法保证整体的原子性和一致性。
- 调试困难:由于原子操作的底层实现较为复杂,在出现问题时,调试和排查错误可能会更加困难。